diff options
Diffstat (limited to 'crates/ra_syntax/src/lib.rs')
-rw-r--r-- | crates/ra_syntax/src/lib.rs | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/crates/ra_syntax/src/lib.rs b/crates/ra_syntax/src/lib.rs new file mode 100644 index 000000000..eb271762e --- /dev/null +++ b/crates/ra_syntax/src/lib.rs | |||
@@ -0,0 +1,105 @@ | |||
1 | //! An experimental implementation of [Rust RFC#2256 libsyntax2.0][rfc#2256]. | ||
2 | //! | ||
3 | //! The intent is to be an IDE-ready parser, i.e. one that offers | ||
4 | //! | ||
5 | //! - easy and fast incremental re-parsing, | ||
6 | //! - graceful handling of errors, and | ||
7 | //! - maintains all information in the source file. | ||
8 | //! | ||
9 | //! For more information, see [the RFC][rfc#2265], or [the working draft][RFC.md]. | ||
10 | //! | ||
11 | //! [rfc#2256]: <https://github.com/rust-lang/rfcs/pull/2256> | ||
12 | //! [RFC.md]: <https://github.com/matklad/libsyntax2/blob/master/docs/RFC.md> | ||
13 | |||
14 | #![forbid( | ||
15 | missing_debug_implementations, | ||
16 | unconditional_recursion, | ||
17 | future_incompatible | ||
18 | )] | ||
19 | #![deny(bad_style, missing_docs)] | ||
20 | #![allow(missing_docs)] | ||
21 | //#![warn(unreachable_pub)] // rust-lang/rust#47816 | ||
22 | |||
23 | extern crate itertools; | ||
24 | extern crate unicode_xid; | ||
25 | extern crate drop_bomb; | ||
26 | extern crate parking_lot; | ||
27 | extern crate smol_str; | ||
28 | extern crate text_unit; | ||
29 | |||
30 | #[cfg(test)] | ||
31 | #[macro_use] | ||
32 | extern crate test_utils; | ||
33 | |||
34 | pub mod algo; | ||
35 | pub mod ast; | ||
36 | mod lexer; | ||
37 | #[macro_use] | ||
38 | mod token_set; | ||
39 | mod parser_api; | ||
40 | mod grammar; | ||
41 | mod parser_impl; | ||
42 | mod reparsing; | ||
43 | |||
44 | mod syntax_kinds; | ||
45 | mod yellow; | ||
46 | /// Utilities for simple uses of the parser. | ||
47 | pub mod utils; | ||
48 | pub mod text_utils; | ||
49 | |||
50 | pub use { | ||
51 | text_unit::{TextRange, TextUnit}, | ||
52 | smol_str::SmolStr, | ||
53 | ast::AstNode, | ||
54 | lexer::{tokenize, Token}, | ||
55 | syntax_kinds::SyntaxKind, | ||
56 | yellow::{SyntaxNode, SyntaxNodeRef, OwnedRoot, RefRoot, TreeRoot, SyntaxError}, | ||
57 | reparsing::AtomEdit, | ||
58 | }; | ||
59 | |||
60 | use { | ||
61 | yellow::{GreenNode, SyntaxRoot}, | ||
62 | }; | ||
63 | |||
64 | #[derive(Clone, Debug, Hash)] | ||
65 | pub struct File { | ||
66 | root: SyntaxNode | ||
67 | } | ||
68 | |||
69 | impl File { | ||
70 | fn new(green: GreenNode, errors: Vec<SyntaxError>) -> File { | ||
71 | let root = SyntaxRoot::new(green, errors); | ||
72 | let root = SyntaxNode::new_owned(root); | ||
73 | if cfg!(debug_assertions) { | ||
74 | utils::validate_block_structure(root.borrowed()); | ||
75 | } | ||
76 | File { root } | ||
77 | } | ||
78 | pub fn parse(text: &str) -> File { | ||
79 | let tokens = tokenize(&text); | ||
80 | let (green, errors) = parser_impl::parse_with::<yellow::GreenBuilder>( | ||
81 | text, &tokens, grammar::root, | ||
82 | ); | ||
83 | File::new(green, errors) | ||
84 | } | ||
85 | pub fn reparse(&self, edit: &AtomEdit) -> File { | ||
86 | self.incremental_reparse(edit).unwrap_or_else(|| self.full_reparse(edit)) | ||
87 | } | ||
88 | pub fn incremental_reparse(&self, edit: &AtomEdit) -> Option<File> { | ||
89 | reparsing::incremental_reparse(self.syntax(), edit, self.errors()) | ||
90 | .map(|(green_node, errors)| File::new(green_node, errors)) | ||
91 | } | ||
92 | fn full_reparse(&self, edit: &AtomEdit) -> File { | ||
93 | let text = text_utils::replace_range(self.syntax().text().to_string(), edit.delete, &edit.insert); | ||
94 | File::parse(&text) | ||
95 | } | ||
96 | pub fn ast(&self) -> ast::Root { | ||
97 | ast::Root::cast(self.syntax()).unwrap() | ||
98 | } | ||
99 | pub fn syntax(&self) -> SyntaxNodeRef { | ||
100 | self.root.borrowed() | ||
101 | } | ||
102 | pub fn errors(&self) -> Vec<SyntaxError> { | ||
103 | self.syntax().root.syntax_root().errors.clone() | ||
104 | } | ||
105 | } | ||