apache / apache/datafusion-sqlparser-rs

Question: why is the Visitor trait limited to statements, relations & expressions?

オープン
#934 コメント 25 件 リアクション 0 件 担当者 0 名 GitHub で見る
主要言語
Rust
スター
3.5k
フォーク
772
平均マージ
4日 9時間
マージ済み PR(30日)
17

説明

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))
}
}
```

コントリビューションガイド

このリポジトリのコントリビューションガイドは索引されていません

調査の方向性

既存の Visitor trait と Visit の derive macro を確認し、その後 src/ast/mod.rs にある AST ノードの定義を調査します。まず、RawVisitor adapter の設計とノードごとの hook のどちらが望ましいかを maintainer に確認してください。合意された汎用的な Visitor API を実装し、既存の Visitor の動作を維持できれば完了です。

索引モデルが issue の本文から書いたものです。

評価

技術スタック
rust
領域
compilers
issue の種類
機能追加
難易度
5/5
見積もり時間
1週間以上
活発さ
停滞
明瞭さ
おおむね明確
初心者へのやさしさ
25/100

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。