aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_syntax/src/lib.rs
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2019-07-18 21:19:35 +0100
committerbors[bot] <26634292+bors[bot]@users.noreply.github.com>2019-07-18 21:19:35 +0100
commit58d4983ba5745975446d60f2886d96f8d2adf0f2 (patch)
tree2336c03a0eeef98ac375868bd27dfe7e50668869 /crates/ra_syntax/src/lib.rs
parentabe72424a647a31840eb952d42905f83628a623c (diff)
parentdf33e7685bdb0f63bf6aa809b9046708d563a1a7 (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/src/lib.rs')
-rw-r--r--crates/ra_syntax/src/lib.rs51
1 files changed, 38 insertions, 13 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)]
61pub struct Parse { 61pub 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
66impl Parse { 66impl<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
72impl<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 { 94impl<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
100impl 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
129impl 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.
112pub use crate::ast::SourceFile; 137pub 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));