apache / apache/datafusion-sqlparser-rs
Question: why is the Visitor trait limited to statements, relations & expressions?
- Langage dominant
- Rust
- Étoiles
- 3.5k
- Forks
- 772
- Merge moyen
- 4 j 9 h
- PR mergées (30 j)
- 17
Description
What is the reason for that particular design decision versus providing a more general `Visitor` implementation?
Two options for a generalised Visitor trait come to mind:
1. expose pre + post trait method variants for every AST node type, or
2. expose only two trait methods (`pre_visit` + `post_visit`) with signatures like `fn pre_visit(&mut self, node: &AstNode) -> ControlFlow` - where `AstNode` is an enum with a wrapper variant for every AST node type found in `src/ast/mod.rs` and can be `match`ed against.
Would the maintainers be interested in a PR that implements one of the above two approaches?
My preference would be for option 2 because it would not break the trait when node types are added/removed.
Suggested approach:
1. Define a new `RawVisitor` trait (and `RawVisitorMut` trait) like this:
```rust
pub trait RawVisitor {
type Break;
fn pre_visit(&mut self, node: &AstNode) -> ControlFlow;
fn post_visit(&mut self, node: &AstNode) -> ControlFlow;
}
```
2. Define an adapter type (`RawVisitorAdapter` ?) that accepts a `V: Visitor` generic argument and implements `RawVisitor` & `RawVisitorMut`, which calls the appropriate method on `V` (or none at all)
```rust
struct RawVisitorAdapter(v);
impl RawVisitor for RawVisitorAdapter {
type Break = V::Break;
fn pre_visit(&mut self, node: &AstNode) -> ControlFlow {
match node {
AstNode(Statement) => self.0.pre_visit_statement(...),
// etc
}
}
fn post_visit(&mut self, node: &AstNode) -> ControlFlow;
}
```
3. Change the `Visit` derivation macros to generate code in terms of `RawVisitor` & `RawVisitorMut` instead of `Visitor`, like this:
```rust
pub trait Visit {
fn visit_raw(&self, visitor: &mut V) -> ControlFlow;
// This has an identical signature to the existing trait, but has a default implementation
fn visit(&self, visitor: &mut V) -> ControlFlow {
self.visit_raw(RawVisitorAdapter::new(visitor))
}
}
```
Guide de contribution
Aucun guide de contribution indexé pour ce dépôt
Piste de recherche
Examinez les traits Visitor existants et les macros de dérivation de Visit, puis inspectez les définitions des nœuds AST dans src/ast/mod.rs. Confirmez d’abord avec les maintainers si la conception de l’adaptateur RawVisitor ou des hooks par nœud est souhaitée ; la tâche est terminée lorsque l’API Visitor généralisée convenue est implémentée tout en préservant le comportement existant de Visitor.
Rédigé par le modèle d'indexation à partir du texte de l'issue.
Évaluation
- Stack technique
- rust
- Domaine
- compilers
- Type d'issue
- Fonctionnalité
- Difficulté
- 5/5
- Temps estimé
- Plus d'une semaine
- Activité
- À l'abandon
- Clarté
- Plutôt claire
- Accessibilité débutants
- 25/100