aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_syntax/src/algo/visit.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_syntax/src/algo/visit.rs')
-rw-r--r--crates/ra_syntax/src/algo/visit.rs112
1 files changed, 0 insertions, 112 deletions
diff --git a/crates/ra_syntax/src/algo/visit.rs b/crates/ra_syntax/src/algo/visit.rs
deleted file mode 100644
index 4df275ba4..000000000
--- a/crates/ra_syntax/src/algo/visit.rs
+++ /dev/null
@@ -1,112 +0,0 @@
1//! FIXME: write short doc here
2
3use crate::{AstNode, SyntaxNode};
4
5use std::marker::PhantomData;
6
7pub fn visitor<'a, T>() -> impl Visitor<'a, Output = T> {
8 EmptyVisitor { ph: PhantomData }
9}
10
11pub fn visitor_ctx<'a, T, C>(ctx: C) -> impl VisitorCtx<'a, Output = T, Ctx = C> {
12 EmptyVisitorCtx { ph: PhantomData, ctx }
13}
14
15pub trait Visitor<'a>: Sized {
16 type Output;
17 fn accept(self, node: &'a SyntaxNode) -> Option<Self::Output>;
18 fn visit<N, F>(self, f: F) -> Vis<Self, N, F>
19 where
20 N: AstNode + 'a,
21 F: FnOnce(N) -> Self::Output,
22 {
23 Vis { inner: self, f, ph: PhantomData }
24 }
25}
26
27pub trait VisitorCtx<'a>: Sized {
28 type Output;
29 type Ctx;
30 fn accept(self, node: &'a SyntaxNode) -> Result<Self::Output, Self::Ctx>;
31 fn visit<N, F>(self, f: F) -> VisCtx<Self, N, F>
32 where
33 N: AstNode + 'a,
34 F: FnOnce(N, Self::Ctx) -> Self::Output,
35 {
36 VisCtx { inner: self, f, ph: PhantomData }
37 }
38}
39
40#[derive(Debug)]
41struct EmptyVisitor<T> {
42 ph: PhantomData<fn() -> T>,
43}
44
45impl<'a, T> Visitor<'a> for EmptyVisitor<T> {
46 type Output = T;
47
48 fn accept(self, _node: &'a SyntaxNode) -> Option<T> {
49 None
50 }
51}
52
53#[derive(Debug)]
54struct EmptyVisitorCtx<T, C> {
55 ctx: C,
56 ph: PhantomData<fn() -> T>,
57}
58
59impl<'a, T, C> VisitorCtx<'a> for EmptyVisitorCtx<T, C> {
60 type Output = T;
61 type Ctx = C;
62
63 fn accept(self, _node: &'a SyntaxNode) -> Result<T, C> {
64 Err(self.ctx)
65 }
66}
67
68#[derive(Debug)]
69pub struct Vis<V, N, F> {
70 inner: V,
71 f: F,
72 ph: PhantomData<fn(N)>,
73}
74
75impl<'a, V, N, F> Visitor<'a> for Vis<V, N, F>
76where
77 V: Visitor<'a>,
78 N: AstNode + 'a,
79 F: FnOnce(N) -> <V as Visitor<'a>>::Output,
80{
81 type Output = <V as Visitor<'a>>::Output;
82
83 fn accept(self, node: &'a SyntaxNode) -> Option<Self::Output> {
84 let Vis { inner, f, .. } = self;
85 inner.accept(node).or_else(|| N::cast(node.clone()).map(f))
86 }
87}
88
89#[derive(Debug)]
90pub struct VisCtx<V, N, F> {
91 inner: V,
92 f: F,
93 ph: PhantomData<fn(N)>,
94}
95
96impl<'a, V, N, F> VisitorCtx<'a> for VisCtx<V, N, F>
97where
98 V: VisitorCtx<'a>,
99 N: AstNode + 'a,
100 F: FnOnce(N, <V as VisitorCtx<'a>>::Ctx) -> <V as VisitorCtx<'a>>::Output,
101{
102 type Output = <V as VisitorCtx<'a>>::Output;
103 type Ctx = <V as VisitorCtx<'a>>::Ctx;
104
105 fn accept(self, node: &'a SyntaxNode) -> Result<Self::Output, Self::Ctx> {
106 let VisCtx { inner, f, .. } = self;
107 inner.accept(node).or_else(|ctx| match N::cast(node.clone()) {
108 None => Err(ctx),
109 Some(node) => Ok(f(node, ctx)),
110 })
111 }
112}