diff options
author | Aleksey Kladov <[email protected]> | 2019-01-23 14:37:10 +0000 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2019-01-23 14:37:10 +0000 |
commit | 7b901f86cd1d0198994e5a2ab7eea18f444dd148 (patch) | |
tree | dfe8364efeeaca6f8f32e1d922fb615119b8012b /crates/ra_syntax/src | |
parent | 81fcfc55d247bfe6090741f2e4ae9aa89947bf32 (diff) |
move SyntaxPtr to ra_syntax
Diffstat (limited to 'crates/ra_syntax/src')
-rw-r--r-- | crates/ra_syntax/src/lib.rs | 2 | ||||
-rw-r--r-- | crates/ra_syntax/src/ptr.rs | 53 |
2 files changed, 55 insertions, 0 deletions
diff --git a/crates/ra_syntax/src/lib.rs b/crates/ra_syntax/src/lib.rs index bc311cbbc..97b196118 100644 --- a/crates/ra_syntax/src/lib.rs +++ b/crates/ra_syntax/src/lib.rs | |||
@@ -35,6 +35,7 @@ mod syntax_kinds; | |||
35 | pub mod utils; | 35 | pub mod utils; |
36 | mod validation; | 36 | mod validation; |
37 | mod yellow; | 37 | mod yellow; |
38 | mod ptr; | ||
38 | 39 | ||
39 | pub use rowan::{SmolStr, TextRange, TextUnit}; | 40 | pub use rowan::{SmolStr, TextRange, TextUnit}; |
40 | pub use crate::{ | 41 | pub use crate::{ |
@@ -42,6 +43,7 @@ pub use crate::{ | |||
42 | lexer::{tokenize, Token}, | 43 | lexer::{tokenize, Token}, |
43 | syntax_kinds::SyntaxKind, | 44 | syntax_kinds::SyntaxKind, |
44 | yellow::{Direction, SyntaxError, SyntaxNode, WalkEvent, Location, TreeArc}, | 45 | yellow::{Direction, SyntaxError, SyntaxNode, WalkEvent, Location, TreeArc}, |
46 | ptr::SyntaxNodePtr, | ||
45 | }; | 47 | }; |
46 | 48 | ||
47 | use ra_text_edit::AtomTextEdit; | 49 | use ra_text_edit::AtomTextEdit; |
diff --git a/crates/ra_syntax/src/ptr.rs b/crates/ra_syntax/src/ptr.rs new file mode 100644 index 000000000..e8c40e5d3 --- /dev/null +++ b/crates/ra_syntax/src/ptr.rs | |||
@@ -0,0 +1,53 @@ | |||
1 | use crate::{ | ||
2 | AstNode, SourceFile, SyntaxKind, SyntaxNode, TextRange, | ||
3 | algo::generate, | ||
4 | }; | ||
5 | |||
6 | /// A pointer to a syntax node inside a file. It can be used to remember a | ||
7 | /// specific node across reparses of the same file. | ||
8 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | ||
9 | pub struct SyntaxNodePtr { | ||
10 | range: TextRange, | ||
11 | kind: SyntaxKind, | ||
12 | } | ||
13 | |||
14 | impl SyntaxNodePtr { | ||
15 | pub fn new(node: &SyntaxNode) -> SyntaxNodePtr { | ||
16 | SyntaxNodePtr { | ||
17 | range: node.range(), | ||
18 | kind: node.kind(), | ||
19 | } | ||
20 | } | ||
21 | |||
22 | pub fn to_node(self, source_file: &SourceFile) -> &SyntaxNode { | ||
23 | generate(Some(source_file.syntax()), |&node| { | ||
24 | node.children() | ||
25 | .find(|it| self.range.is_subrange(&it.range())) | ||
26 | }) | ||
27 | .find(|it| it.range() == self.range && it.kind() == self.kind) | ||
28 | .unwrap_or_else(|| panic!("can't resolve local ptr to SyntaxNode: {:?}", self)) | ||
29 | } | ||
30 | |||
31 | pub fn range(self) -> TextRange { | ||
32 | self.range | ||
33 | } | ||
34 | |||
35 | pub fn kind(self) -> SyntaxKind { | ||
36 | self.kind | ||
37 | } | ||
38 | } | ||
39 | |||
40 | #[test] | ||
41 | fn test_local_syntax_ptr() { | ||
42 | use crate::{ast, AstNode}; | ||
43 | |||
44 | let file = SourceFile::parse("struct Foo { f: u32, }"); | ||
45 | let field = file | ||
46 | .syntax() | ||
47 | .descendants() | ||
48 | .find_map(ast::NamedFieldDef::cast) | ||
49 | .unwrap(); | ||
50 | let ptr = SyntaxNodePtr::new(field.syntax()); | ||
51 | let field_syntax = ptr.to_node(&file); | ||
52 | assert_eq!(field.syntax(), &*field_syntax); | ||
53 | } | ||