mirror of
https://github.com/rust-lang/rust-analyzer
synced 2025-01-13 13:48:50 +00:00
Introduce drop-bomb
This commit is contained in:
parent
37e1625f01
commit
ecd5da5b0c
3 changed files with 43 additions and 20 deletions
21
src/drop_bomb.rs
Normal file
21
src/drop_bomb.rs
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
use std::borrow::Cow;
|
||||||
|
|
||||||
|
pub struct DropBomb {
|
||||||
|
msg: Cow<'static, str>,
|
||||||
|
defused: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DropBomb {
|
||||||
|
pub fn new(msg: impl Into<Cow<'static, str>>) -> DropBomb {
|
||||||
|
DropBomb { msg: msg.into(), defused: false }
|
||||||
|
}
|
||||||
|
pub fn defuse(&mut self) { self.defused = true }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Drop for DropBomb {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
if !self.defused && !::std::thread::panicking() {
|
||||||
|
panic!("{}", self.msg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -31,6 +31,7 @@ mod lexer;
|
||||||
mod parser_api;
|
mod parser_api;
|
||||||
mod grammar;
|
mod grammar;
|
||||||
mod parser_impl;
|
mod parser_impl;
|
||||||
|
mod drop_bomb;
|
||||||
|
|
||||||
mod syntax_kinds;
|
mod syntax_kinds;
|
||||||
/// Utilities for simple uses of the parser.
|
/// Utilities for simple uses of the parser.
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
use {
|
use {
|
||||||
parser_impl::ParserImpl,
|
parser_impl::ParserImpl,
|
||||||
SyntaxKind::{self, ERROR},
|
SyntaxKind::{self, ERROR},
|
||||||
|
drop_bomb::DropBomb,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
|
@ -76,7 +77,7 @@ impl<'t> Parser<'t> {
|
||||||
/// consumed between the `start` and the corresponding `Marker::complete`
|
/// consumed between the `start` and the corresponding `Marker::complete`
|
||||||
/// belong to the same node.
|
/// belong to the same node.
|
||||||
pub(crate) fn start(&mut self) -> Marker {
|
pub(crate) fn start(&mut self) -> Marker {
|
||||||
Marker(self.0.start())
|
Marker::new(self.0.start())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Advances the parser by one token.
|
/// Advances the parser by one token.
|
||||||
|
@ -131,31 +132,31 @@ impl<'t> Parser<'t> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// See `Parser::start`.
|
/// See `Parser::start`.
|
||||||
pub(crate) struct Marker(u32);
|
pub(crate) struct Marker {
|
||||||
|
pos: u32,
|
||||||
|
bomb: DropBomb,
|
||||||
|
}
|
||||||
|
|
||||||
impl Marker {
|
impl Marker {
|
||||||
|
fn new(pos: u32) -> Marker {
|
||||||
|
Marker {
|
||||||
|
pos,
|
||||||
|
bomb: DropBomb::new("Marker must be either completed or abandoned")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Finishes the syntax tree node and assigns `kind` to it.
|
/// Finishes the syntax tree node and assigns `kind` to it.
|
||||||
pub(crate) fn complete(self, p: &mut Parser, kind: SyntaxKind) -> CompletedMarker {
|
pub(crate) fn complete(mut self, p: &mut Parser, kind: SyntaxKind) -> CompletedMarker {
|
||||||
let pos = self.0;
|
self.bomb.defuse();
|
||||||
::std::mem::forget(self);
|
p.0.complete(self.pos, kind);
|
||||||
p.0.complete(pos, kind);
|
CompletedMarker(self.pos)
|
||||||
CompletedMarker(pos)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Abandons the syntax tree node. All its children
|
/// Abandons the syntax tree node. All its children
|
||||||
/// are attached to its parent instead.
|
/// are attached to its parent instead.
|
||||||
pub(crate) fn abandon(self, p: &mut Parser) {
|
pub(crate) fn abandon(mut self, p: &mut Parser) {
|
||||||
let pos = self.0;
|
self.bomb.defuse();
|
||||||
::std::mem::forget(self);
|
p.0.abandon(self.pos);
|
||||||
p.0.abandon(pos);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Drop for Marker {
|
|
||||||
fn drop(&mut self) {
|
|
||||||
if !::std::thread::panicking() {
|
|
||||||
panic!("Marker must be either completed or abandoned");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -170,6 +171,6 @@ impl CompletedMarker {
|
||||||
/// `B` before starting `A`. `precede` allows to do exactly
|
/// `B` before starting `A`. `precede` allows to do exactly
|
||||||
/// that. See also docs about `forward_parent` in `Event::Start`.
|
/// that. See also docs about `forward_parent` in `Event::Start`.
|
||||||
pub(crate) fn precede(self, p: &mut Parser) -> Marker {
|
pub(crate) fn precede(self, p: &mut Parser) -> Marker {
|
||||||
Marker(p.0.precede(self.0))
|
Marker::new(p.0.precede(self.0))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue