diff options
author | Aleksey Kladov <[email protected]> | 2018-08-01 09:58:19 +0100 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2018-08-01 09:58:19 +0100 |
commit | ecd5da5b0cae5b3af95f5b86a8157a1f57a944c5 (patch) | |
tree | eb14d6c340e2ee96666c90637c1ca3fc7ba1b5ea /src/parser_api.rs | |
parent | 37e1625f0139da07c2690b6ee6ca7eae5ebb061a (diff) |
Introduce drop-bomb
Diffstat (limited to 'src/parser_api.rs')
-rw-r--r-- | src/parser_api.rs | 41 |
1 files changed, 21 insertions, 20 deletions
diff --git a/src/parser_api.rs b/src/parser_api.rs index d12f773b2..3cad91976 100644 --- a/src/parser_api.rs +++ b/src/parser_api.rs | |||
@@ -1,6 +1,7 @@ | |||
1 | use { | 1 | use { |
2 | parser_impl::ParserImpl, | 2 | parser_impl::ParserImpl, |
3 | SyntaxKind::{self, ERROR}, | 3 | SyntaxKind::{self, ERROR}, |
4 | drop_bomb::DropBomb, | ||
4 | }; | 5 | }; |
5 | 6 | ||
6 | #[derive(Clone, Copy)] | 7 | #[derive(Clone, Copy)] |
@@ -76,7 +77,7 @@ impl<'t> Parser<'t> { | |||
76 | /// consumed between the `start` and the corresponding `Marker::complete` | 77 | /// consumed between the `start` and the corresponding `Marker::complete` |
77 | /// belong to the same node. | 78 | /// belong to the same node. |
78 | pub(crate) fn start(&mut self) -> Marker { | 79 | pub(crate) fn start(&mut self) -> Marker { |
79 | Marker(self.0.start()) | 80 | Marker::new(self.0.start()) |
80 | } | 81 | } |
81 | 82 | ||
82 | /// Advances the parser by one token. | 83 | /// Advances the parser by one token. |
@@ -131,31 +132,31 @@ impl<'t> Parser<'t> { | |||
131 | } | 132 | } |
132 | 133 | ||
133 | /// See `Parser::start`. | 134 | /// See `Parser::start`. |
134 | pub(crate) struct Marker(u32); | 135 | pub(crate) struct Marker { |
136 | pos: u32, | ||
137 | bomb: DropBomb, | ||
138 | } | ||
135 | 139 | ||
136 | impl Marker { | 140 | impl Marker { |
141 | fn new(pos: u32) -> Marker { | ||
142 | Marker { | ||
143 | pos, | ||
144 | bomb: DropBomb::new("Marker must be either completed or abandoned") | ||
145 | } | ||
146 | } | ||
147 | |||
137 | /// Finishes the syntax tree node and assigns `kind` to it. | 148 | /// Finishes the syntax tree node and assigns `kind` to it. |
138 | pub(crate) fn complete(self, p: &mut Parser, kind: SyntaxKind) -> CompletedMarker { | 149 | pub(crate) fn complete(mut self, p: &mut Parser, kind: SyntaxKind) -> CompletedMarker { |
139 | let pos = self.0; | 150 | self.bomb.defuse(); |
140 | ::std::mem::forget(self); | 151 | p.0.complete(self.pos, kind); |
141 | p.0.complete(pos, kind); | 152 | CompletedMarker(self.pos) |
142 | CompletedMarker(pos) | ||
143 | } | 153 | } |
144 | 154 | ||
145 | /// Abandons the syntax tree node. All its children | 155 | /// Abandons the syntax tree node. All its children |
146 | /// are attached to its parent instead. | 156 | /// are attached to its parent instead. |
147 | pub(crate) fn abandon(self, p: &mut Parser) { | 157 | pub(crate) fn abandon(mut self, p: &mut Parser) { |
148 | let pos = self.0; | 158 | self.bomb.defuse(); |
149 | ::std::mem::forget(self); | 159 | p.0.abandon(self.pos); |
150 | p.0.abandon(pos); | ||
151 | } | ||
152 | } | ||
153 | |||
154 | impl Drop for Marker { | ||
155 | fn drop(&mut self) { | ||
156 | if !::std::thread::panicking() { | ||
157 | panic!("Marker must be either completed or abandoned"); | ||
158 | } | ||
159 | } | 160 | } |
160 | } | 161 | } |
161 | 162 | ||
@@ -170,6 +171,6 @@ impl CompletedMarker { | |||
170 | /// `B` before starting `A`. `precede` allows to do exactly | 171 | /// `B` before starting `A`. `precede` allows to do exactly |
171 | /// that. See also docs about `forward_parent` in `Event::Start`. | 172 | /// that. See also docs about `forward_parent` in `Event::Start`. |
172 | pub(crate) fn precede(self, p: &mut Parser) -> Marker { | 173 | pub(crate) fn precede(self, p: &mut Parser) -> Marker { |
173 | Marker(p.0.precede(self.0)) | 174 | Marker::new(p.0.precede(self.0)) |
174 | } | 175 | } |
175 | } | 176 | } |