mirror of
https://github.com/fish-shell/fish-shell.git
synced 2026-05-30 11:21:15 -03:00
ast: clean up NodeVisitorMut
This eliminates a bunch of the different functions from NodeVisitorMut. It also removes the runtime polymorphism - now it's a generic instead of using &dyn. The reason is that there's only one implementation of NodeVisitorMut so there's no size savings from polymorphism.
This commit is contained in:
94
src/ast.rs
94
src/ast.rs
@@ -63,30 +63,19 @@ pub struct MissingEndError {
|
||||
|
||||
pub type VisitResult = ControlFlow<MissingEndError>;
|
||||
|
||||
/**
|
||||
* Similar to NodeVisitor, but for mutable nodes.
|
||||
*
|
||||
* Note that this breaks out various node types into their own functions.
|
||||
*/
|
||||
/// Similar to NodeVisitor, but for mutable nodes.
|
||||
trait NodeVisitorMut {
|
||||
/// will_visit (did_visit) is called before (after) a node's fields are visited.
|
||||
fn will_visit_fields_of(&mut self, node: &mut dyn NodeMut);
|
||||
fn visit_mut(&mut self, node: &mut dyn NodeMut) -> VisitResult;
|
||||
fn did_visit_fields_of<'a>(&'a mut self, node: &'a dyn NodeMut, flow: VisitResult);
|
||||
fn will_visit_fields_of<N: NodeMut>(&mut self, node: &mut N);
|
||||
fn visit_mut<N: NodeMut>(&mut self, node: &mut N) -> VisitResult;
|
||||
fn did_visit_fields_of<'a, N: NodeMut>(&'a mut self, node: &'a mut N, flow: VisitResult);
|
||||
|
||||
fn visit_argument_or_redirection(&mut self, _node: &mut ArgumentOrRedirection) -> VisitResult;
|
||||
fn visit_block_statement_header(&mut self, _node: &mut BlockStatementHeader) -> VisitResult;
|
||||
fn visit_statement(&mut self, _node: &mut Statement) -> VisitResult;
|
||||
|
||||
fn visit_decorated_statement_decorator(
|
||||
&mut self,
|
||||
_node: &mut Option<DecoratedStatementDecorator>,
|
||||
);
|
||||
fn visit_job_conjunction_decorator(&mut self, _node: &mut Option<JobConjunctionDecorator>);
|
||||
fn visit_else_clause(&mut self, _node: &mut Option<ElseClause>);
|
||||
fn visit_semi_nl(&mut self, _node: &mut Option<SemiNl>);
|
||||
fn visit_time(&mut self, _node: &mut Option<KeywordTime>);
|
||||
fn visit_token_background(&mut self, _node: &mut Option<TokenBackground>);
|
||||
// Visit an optional field, perhaps populating it.
|
||||
fn visit_optional_mut<N: NodeMut + CheckParse>(&mut self, node: &mut Option<N>) -> VisitResult;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -95,11 +84,11 @@ fn visit_decorated_statement_decorator(
|
||||
* It generally invokes the right visit() method on each of its children.
|
||||
*/
|
||||
trait AcceptorMut {
|
||||
fn accept_mut(&mut self, visitor: &mut dyn NodeVisitorMut);
|
||||
fn accept_mut<V: NodeVisitorMut>(&mut self, visitor: &mut V);
|
||||
}
|
||||
|
||||
impl<T: AcceptorMut> AcceptorMut for Option<T> {
|
||||
fn accept_mut(&mut self, visitor: &mut dyn NodeVisitorMut) {
|
||||
fn accept_mut<V: NodeVisitorMut>(&mut self, visitor: &mut V) {
|
||||
if let Some(node) = self {
|
||||
node.accept_mut(visitor)
|
||||
}
|
||||
@@ -364,7 +353,7 @@ fn allows_keyword(&self, kw: ParseKeyword) -> bool {
|
||||
}
|
||||
|
||||
/// This is for optional values and for lists.
|
||||
trait CheckParse {
|
||||
trait CheckParse: Default {
|
||||
/// A true return means we should descend into the production, false means stop.
|
||||
fn can_be_parsed(pop: &mut Populator<'_>) -> bool;
|
||||
}
|
||||
@@ -410,7 +399,7 @@ fn accept<'a>(&'a self, visitor: &mut dyn NodeVisitor<'a>) {}
|
||||
}
|
||||
impl AcceptorMut for $name {
|
||||
#[allow(unused_variables)]
|
||||
fn accept_mut(&mut self, visitor: &mut dyn NodeVisitorMut) {
|
||||
fn accept_mut<V: NodeVisitorMut>(&mut self, visitor: &mut V) {
|
||||
visitor.will_visit_fields_of(self);
|
||||
visitor.did_visit_fields_of(self, VisitResult::Continue(()));
|
||||
}
|
||||
@@ -547,7 +536,7 @@ fn accept<'a>(&'a self, visitor: &mut dyn NodeVisitor<'a>) {
|
||||
}
|
||||
|
||||
impl AcceptorMut for $name {
|
||||
fn accept_mut(&mut self, visitor: &mut dyn NodeVisitorMut) {
|
||||
fn accept_mut<V: NodeVisitorMut>(&mut self, visitor: &mut V) {
|
||||
visitor.will_visit_fields_of(self);
|
||||
let flow = self
|
||||
.0
|
||||
@@ -579,7 +568,7 @@ fn accept<'a>(&'a self, visitor: &mut dyn NodeVisitor<'a>){
|
||||
}
|
||||
impl AcceptorMut for $name {
|
||||
#[allow(unused_variables)]
|
||||
fn accept_mut(&mut self, visitor: &mut dyn NodeVisitorMut) {
|
||||
fn accept_mut<V: NodeVisitorMut>(&mut self, visitor: &mut V) {
|
||||
visitor.will_visit_fields_of(self);
|
||||
let flow = visitor_accept_field!(
|
||||
accept_mut,
|
||||
@@ -681,32 +670,10 @@ macro_rules! visit_optional_field {
|
||||
$field:expr,
|
||||
$visitor:ident
|
||||
) => {{
|
||||
visit_optional_field_mut!($field_type, $field, $visitor);
|
||||
VisitResult::Continue(())
|
||||
$visitor.visit_optional_mut(&mut $field)
|
||||
}};
|
||||
}
|
||||
|
||||
macro_rules! visit_optional_field_mut {
|
||||
(DecoratedStatementDecorator, $field:expr, $visitor:ident) => {
|
||||
$visitor.visit_decorated_statement_decorator(&mut $field);
|
||||
};
|
||||
(JobConjunctionDecorator, $field:expr, $visitor:ident) => {
|
||||
$visitor.visit_job_conjunction_decorator(&mut $field);
|
||||
};
|
||||
(ElseClause, $field:expr, $visitor:ident) => {
|
||||
$visitor.visit_else_clause(&mut $field);
|
||||
};
|
||||
(SemiNl, $field:expr, $visitor:ident) => {
|
||||
$visitor.visit_semi_nl(&mut $field);
|
||||
};
|
||||
(KeywordTime, $field:expr, $visitor:ident) => {
|
||||
$visitor.visit_time(&mut $field);
|
||||
};
|
||||
(TokenBackground, $field:expr, $visitor:ident) => {
|
||||
$visitor.visit_token_background(&mut $field);
|
||||
};
|
||||
}
|
||||
|
||||
/// A redirection has an operator like > or 2>, and a target like /dev/null or &1.
|
||||
/// Note that pipes are not redirections.
|
||||
#[derive(Default, Debug)]
|
||||
@@ -748,7 +715,7 @@ fn accept<'a>(&'a self, visitor: &mut dyn NodeVisitor<'a>) {
|
||||
}
|
||||
}
|
||||
impl AcceptorMut for ArgumentOrRedirection {
|
||||
fn accept_mut(&mut self, visitor: &mut dyn NodeVisitorMut) {
|
||||
fn accept_mut<V: NodeVisitorMut>(&mut self, visitor: &mut V) {
|
||||
visitor.will_visit_fields_of(self);
|
||||
let flow = visitor.visit_argument_or_redirection(self);
|
||||
visitor.did_visit_fields_of(self, flow);
|
||||
@@ -842,7 +809,7 @@ fn accept<'a>(&'a self, visitor: &mut dyn NodeVisitor<'a>) {
|
||||
}
|
||||
|
||||
impl AcceptorMut for Statement {
|
||||
fn accept_mut(&mut self, visitor: &mut dyn NodeVisitorMut) {
|
||||
fn accept_mut<V: NodeVisitorMut>(&mut self, visitor: &mut V) {
|
||||
visitor.will_visit_fields_of(self);
|
||||
let flow = visitor.visit_statement(self);
|
||||
visitor.did_visit_fields_of(self, flow);
|
||||
@@ -1473,7 +1440,7 @@ fn accept<'a>(&'a self, visitor: &mut dyn NodeVisitor<'a>) {
|
||||
}
|
||||
}
|
||||
impl AcceptorMut for BlockStatementHeader {
|
||||
fn accept_mut(&mut self, visitor: &mut dyn NodeVisitorMut) {
|
||||
fn accept_mut<V: NodeVisitorMut>(&mut self, visitor: &mut V) {
|
||||
visitor.will_visit_fields_of(self);
|
||||
let flow = visitor.visit_block_statement_header(self);
|
||||
visitor.did_visit_fields_of(self, flow);
|
||||
@@ -2023,7 +1990,7 @@ struct Populator<'a> {
|
||||
}
|
||||
|
||||
impl<'s> NodeVisitorMut for Populator<'s> {
|
||||
fn visit_mut(&mut self, node: &mut dyn NodeMut) -> VisitResult {
|
||||
fn visit_mut<N: NodeMut>(&mut self, node: &mut N) -> VisitResult {
|
||||
use KindMut as KM;
|
||||
match node.kind_mut() {
|
||||
// Leaves
|
||||
@@ -2077,7 +2044,7 @@ fn visit_mut(&mut self, node: &mut dyn NodeMut) -> VisitResult {
|
||||
VisitResult::Continue(())
|
||||
}
|
||||
|
||||
fn will_visit_fields_of(&mut self, node: &mut dyn NodeMut) {
|
||||
fn will_visit_fields_of<N: NodeMut>(&mut self, node: &mut N) {
|
||||
FLOGF!(
|
||||
ast_construction,
|
||||
"%*swill_visit %ls",
|
||||
@@ -2088,7 +2055,7 @@ fn will_visit_fields_of(&mut self, node: &mut dyn NodeMut) {
|
||||
self.depth += 1
|
||||
}
|
||||
|
||||
fn did_visit_fields_of<'a>(&'a mut self, node: &'a dyn NodeMut, flow: VisitResult) {
|
||||
fn did_visit_fields_of<'a, N: NodeMut>(&'a mut self, node: &'a mut N, flow: VisitResult) {
|
||||
self.depth -= 1;
|
||||
|
||||
if self.unwinding {
|
||||
@@ -2195,26 +2162,9 @@ fn visit_statement(&mut self, node: &mut Statement) -> VisitResult {
|
||||
VisitResult::Continue(())
|
||||
}
|
||||
|
||||
fn visit_decorated_statement_decorator(
|
||||
&mut self,
|
||||
node: &mut Option<DecoratedStatementDecorator>,
|
||||
) {
|
||||
*node = self.try_parse::<DecoratedStatementDecorator>();
|
||||
}
|
||||
fn visit_job_conjunction_decorator(&mut self, node: &mut Option<JobConjunctionDecorator>) {
|
||||
*node = self.try_parse::<JobConjunctionDecorator>();
|
||||
}
|
||||
fn visit_else_clause(&mut self, node: &mut Option<ElseClause>) {
|
||||
*node = self.try_parse::<ElseClause>();
|
||||
}
|
||||
fn visit_semi_nl(&mut self, node: &mut Option<SemiNl>) {
|
||||
*node = self.try_parse::<SemiNl>();
|
||||
}
|
||||
fn visit_time(&mut self, node: &mut Option<KeywordTime>) {
|
||||
*node = self.try_parse::<KeywordTime>();
|
||||
}
|
||||
fn visit_token_background(&mut self, node: &mut Option<TokenBackground>) {
|
||||
*node = self.try_parse::<TokenBackground>();
|
||||
fn visit_optional_mut<N: NodeMut + CheckParse>(&mut self, node: &mut Option<N>) -> VisitResult {
|
||||
*node = self.try_parse::<N>();
|
||||
VisitResult::Continue(())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user