diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2019-07-18 21:19:35 +0100 |
---|---|---|
committer | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2019-07-18 21:19:35 +0100 |
commit | 58d4983ba5745975446d60f2886d96f8d2adf0f2 (patch) | |
tree | 2336c03a0eeef98ac375868bd27dfe7e50668869 /crates/ra_syntax | |
parent | abe72424a647a31840eb952d42905f83628a623c (diff) | |
parent | df33e7685bdb0f63bf6aa809b9046708d563a1a7 (diff) |
Merge #1548
1548: use Parse in mbe r=matklad a=matklad
Co-authored-by: Aleksey Kladov <[email protected]>
Diffstat (limited to 'crates/ra_syntax')
-rw-r--r-- | crates/ra_syntax/src/lib.rs | 51 | ||||
-rw-r--r-- | crates/ra_syntax/src/syntax_node.rs | 7 |
2 files changed, 42 insertions, 16 deletions
diff --git a/crates/ra_syntax/src/lib.rs b/crates/ra_syntax/src/lib.rs index 0fa2fe382..534c206a6 100644 --- a/crates/ra_syntax/src/lib.rs +++ b/crates/ra_syntax/src/lib.rs | |||
@@ -43,8 +43,8 @@ pub use crate::{ | |||
43 | ptr::{AstPtr, SyntaxNodePtr}, | 43 | ptr::{AstPtr, SyntaxNodePtr}, |
44 | syntax_error::{Location, SyntaxError, SyntaxErrorKind}, | 44 | syntax_error::{Location, SyntaxError, SyntaxErrorKind}, |
45 | syntax_node::{ | 45 | syntax_node::{ |
46 | Direction, InsertPosition, SyntaxElement, SyntaxNode, SyntaxToken, SyntaxTreeBuilder, | 46 | Direction, InsertPosition, SyntaxElement, SyntaxNode, SyntaxNodeWrapper, SyntaxToken, |
47 | TreeArc, WalkEvent, | 47 | SyntaxTreeBuilder, TreeArc, WalkEvent, |
48 | }, | 48 | }, |
49 | syntax_text::SyntaxText, | 49 | syntax_text::SyntaxText, |
50 | }; | 50 | }; |
@@ -57,14 +57,24 @@ pub use rowan::{SmolStr, TextRange, TextUnit}; | |||
57 | /// | 57 | /// |
58 | /// Note that we always produce a syntax tree, even for completely invalid | 58 | /// Note that we always produce a syntax tree, even for completely invalid |
59 | /// files. | 59 | /// files. |
60 | #[derive(Debug, Clone, PartialEq, Eq)] | 60 | #[derive(Debug, PartialEq, Eq)] |
61 | pub struct Parse { | 61 | pub struct Parse<T: SyntaxNodeWrapper> { |
62 | tree: TreeArc<SourceFile>, | 62 | tree: TreeArc<T>, |
63 | errors: Arc<Vec<SyntaxError>>, | 63 | errors: Arc<Vec<SyntaxError>>, |
64 | } | 64 | } |
65 | 65 | ||
66 | impl Parse { | 66 | impl<T: SyntaxNodeWrapper> Clone for Parse<T> { |
67 | pub fn tree(&self) -> &SourceFile { | 67 | fn clone(&self) -> Parse<T> { |
68 | Parse { tree: self.tree.clone(), errors: self.errors.clone() } | ||
69 | } | ||
70 | } | ||
71 | |||
72 | impl<T: SyntaxNodeWrapper> Parse<T> { | ||
73 | fn new(tree: TreeArc<T>, errors: Vec<SyntaxError>) -> Parse<T> { | ||
74 | Parse { tree, errors: Arc::new(errors) } | ||
75 | } | ||
76 | |||
77 | pub fn tree(&self) -> &T { | ||
68 | &*self.tree | 78 | &*self.tree |
69 | } | 79 | } |
70 | 80 | ||
@@ -72,18 +82,22 @@ impl Parse { | |||
72 | &*self.errors | 82 | &*self.errors |
73 | } | 83 | } |
74 | 84 | ||
75 | pub fn ok(self) -> Result<TreeArc<SourceFile>, Arc<Vec<SyntaxError>>> { | 85 | pub fn ok(self) -> Result<TreeArc<T>, Arc<Vec<SyntaxError>>> { |
76 | if self.errors.is_empty() { | 86 | if self.errors.is_empty() { |
77 | Ok(self.tree) | 87 | Ok(self.tree) |
78 | } else { | 88 | } else { |
79 | Err(self.errors) | 89 | Err(self.errors) |
80 | } | 90 | } |
81 | } | 91 | } |
92 | } | ||
82 | 93 | ||
83 | pub fn reparse(&self, edit: &AtomTextEdit) -> Parse { | 94 | impl<T: AstNode> Parse<T> { |
84 | self.incremental_reparse(edit).unwrap_or_else(|| self.full_reparse(edit)) | 95 | pub fn to_syntax(this: Self) -> Parse<SyntaxNode> { |
96 | Parse { tree: this.tree().syntax().to_owned(), errors: this.errors } | ||
85 | } | 97 | } |
98 | } | ||
86 | 99 | ||
100 | impl Parse<SourceFile> { | ||
87 | pub fn debug_dump(&self) -> String { | 101 | pub fn debug_dump(&self) -> String { |
88 | let mut buf = self.tree.syntax().debug_dump(); | 102 | let mut buf = self.tree.syntax().debug_dump(); |
89 | for err in self.errors.iter() { | 103 | for err in self.errors.iter() { |
@@ -92,7 +106,11 @@ impl Parse { | |||
92 | buf | 106 | buf |
93 | } | 107 | } |
94 | 108 | ||
95 | fn incremental_reparse(&self, edit: &AtomTextEdit) -> Option<Parse> { | 109 | pub fn reparse(&self, edit: &AtomTextEdit) -> Parse<SourceFile> { |
110 | self.incremental_reparse(edit).unwrap_or_else(|| self.full_reparse(edit)) | ||
111 | } | ||
112 | |||
113 | fn incremental_reparse(&self, edit: &AtomTextEdit) -> Option<Parse<SourceFile>> { | ||
96 | // FIXME: validation errors are not handled here | 114 | // FIXME: validation errors are not handled here |
97 | parsing::incremental_reparse(self.tree.syntax(), edit, self.errors.to_vec()).map( | 115 | parsing::incremental_reparse(self.tree.syntax(), edit, self.errors.to_vec()).map( |
98 | |(green_node, errors, _reparsed_range)| Parse { | 116 | |(green_node, errors, _reparsed_range)| Parse { |
@@ -102,12 +120,19 @@ impl Parse { | |||
102 | ) | 120 | ) |
103 | } | 121 | } |
104 | 122 | ||
105 | fn full_reparse(&self, edit: &AtomTextEdit) -> Parse { | 123 | fn full_reparse(&self, edit: &AtomTextEdit) -> Parse<SourceFile> { |
106 | let text = edit.apply(self.tree.syntax().text().to_string()); | 124 | let text = edit.apply(self.tree.syntax().text().to_string()); |
107 | SourceFile::parse(&text) | 125 | SourceFile::parse(&text) |
108 | } | 126 | } |
109 | } | 127 | } |
110 | 128 | ||
129 | impl Parse<SyntaxNode> { | ||
130 | pub fn cast<T: AstNode>(self) -> Option<Parse<T>> { | ||
131 | let node = T::cast(&self.tree)?; | ||
132 | Some(Parse { tree: node.to_owned(), errors: self.errors }) | ||
133 | } | ||
134 | } | ||
135 | |||
111 | /// `SourceFile` represents a parse tree for a single Rust file. | 136 | /// `SourceFile` represents a parse tree for a single Rust file. |
112 | pub use crate::ast::SourceFile; | 137 | pub use crate::ast::SourceFile; |
113 | 138 | ||
@@ -121,7 +146,7 @@ impl SourceFile { | |||
121 | TreeArc::cast(root) | 146 | TreeArc::cast(root) |
122 | } | 147 | } |
123 | 148 | ||
124 | pub fn parse(text: &str) -> Parse { | 149 | pub fn parse(text: &str) -> Parse<SourceFile> { |
125 | let (green, mut errors) = parsing::parse_text(text); | 150 | let (green, mut errors) = parsing::parse_text(text); |
126 | let tree = SourceFile::new(green); | 151 | let tree = SourceFile::new(green); |
127 | errors.extend(validation::validate(&tree)); | 152 | errors.extend(validation::validate(&tree)); |
diff --git a/crates/ra_syntax/src/syntax_node.rs b/crates/ra_syntax/src/syntax_node.rs index a1f9a59b6..e57813a94 100644 --- a/crates/ra_syntax/src/syntax_node.rs +++ b/crates/ra_syntax/src/syntax_node.rs | |||
@@ -18,7 +18,8 @@ use rowan::{GreenNodeBuilder, TransparentNewType}; | |||
18 | 18 | ||
19 | use crate::{ | 19 | use crate::{ |
20 | syntax_error::{SyntaxError, SyntaxErrorKind}, | 20 | syntax_error::{SyntaxError, SyntaxErrorKind}, |
21 | AstNode, SmolStr, SourceFile, SyntaxKind, SyntaxNodePtr, SyntaxText, TextRange, TextUnit, | 21 | AstNode, Parse, SmolStr, SourceFile, SyntaxKind, SyntaxNodePtr, SyntaxText, TextRange, |
22 | TextUnit, | ||
22 | }; | 23 | }; |
23 | 24 | ||
24 | pub use rowan::WalkEvent; | 25 | pub use rowan::WalkEvent; |
@@ -594,13 +595,13 @@ impl SyntaxTreeBuilder { | |||
594 | (green, self.errors) | 595 | (green, self.errors) |
595 | } | 596 | } |
596 | 597 | ||
597 | pub fn finish(self) -> (TreeArc<SyntaxNode>, Vec<SyntaxError>) { | 598 | pub fn finish(self) -> Parse<SyntaxNode> { |
598 | let (green, errors) = self.finish_raw(); | 599 | let (green, errors) = self.finish_raw(); |
599 | let node = SyntaxNode::new(green); | 600 | let node = SyntaxNode::new(green); |
600 | if cfg!(debug_assertions) { | 601 | if cfg!(debug_assertions) { |
601 | crate::validation::validate_block_structure(&node); | 602 | crate::validation::validate_block_structure(&node); |
602 | } | 603 | } |
603 | (node, errors) | 604 | Parse::new(node, errors) |
604 | } | 605 | } |
605 | 606 | ||
606 | pub fn token(&mut self, kind: SyntaxKind, text: SmolStr) { | 607 | pub fn token(&mut self, kind: SyntaxKind, text: SmolStr) { |