diff options
-rw-r--r-- | crates/ra_db/src/lib.rs | 6 | ||||
-rw-r--r-- | crates/ra_ide_api/src/completion/completion_context.rs | 4 | ||||
-rw-r--r-- | crates/ra_ide_api/src/status.rs | 6 | ||||
-rw-r--r-- | crates/ra_ide_api/src/symbol_index.rs | 4 | ||||
-rw-r--r-- | crates/ra_syntax/src/lib.rs | 47 |
5 files changed, 44 insertions, 23 deletions
diff --git a/crates/ra_db/src/lib.rs b/crates/ra_db/src/lib.rs index 11e18a03d..b82d1bda0 100644 --- a/crates/ra_db/src/lib.rs +++ b/crates/ra_db/src/lib.rs | |||
@@ -5,7 +5,7 @@ mod input; | |||
5 | use std::{panic, sync::Arc}; | 5 | use std::{panic, sync::Arc}; |
6 | 6 | ||
7 | use ra_prof::profile; | 7 | use ra_prof::profile; |
8 | use ra_syntax::{Parse, SourceFile, TextRange, TextUnit}; | 8 | use ra_syntax::{ast, Parse, SourceFile, TextRange, TextUnit}; |
9 | use relative_path::RelativePathBuf; | 9 | use relative_path::RelativePathBuf; |
10 | 10 | ||
11 | pub use crate::{ | 11 | pub use crate::{ |
@@ -74,7 +74,7 @@ pub trait SourceDatabase: CheckCanceled + std::fmt::Debug { | |||
74 | fn file_text(&self, file_id: FileId) -> Arc<String>; | 74 | fn file_text(&self, file_id: FileId) -> Arc<String>; |
75 | // Parses the file into the syntax tree. | 75 | // Parses the file into the syntax tree. |
76 | #[salsa::invoke(parse_query)] | 76 | #[salsa::invoke(parse_query)] |
77 | fn parse(&self, file_id: FileId) -> Parse; | 77 | fn parse(&self, file_id: FileId) -> Parse<ast::SourceFile>; |
78 | /// Path to a file, relative to the root of its source root. | 78 | /// Path to a file, relative to the root of its source root. |
79 | #[salsa::input] | 79 | #[salsa::input] |
80 | fn file_relative_path(&self, file_id: FileId) -> RelativePathBuf; | 80 | fn file_relative_path(&self, file_id: FileId) -> RelativePathBuf; |
@@ -98,7 +98,7 @@ fn source_root_crates(db: &impl SourceDatabase, id: SourceRootId) -> Arc<Vec<Cra | |||
98 | Arc::new(res) | 98 | Arc::new(res) |
99 | } | 99 | } |
100 | 100 | ||
101 | fn parse_query(db: &impl SourceDatabase, file_id: FileId) -> Parse { | 101 | fn parse_query(db: &impl SourceDatabase, file_id: FileId) -> Parse<ast::SourceFile> { |
102 | let _p = profile("parse_query"); | 102 | let _p = profile("parse_query"); |
103 | let text = db.file_text(file_id); | 103 | let text = db.file_text(file_id); |
104 | SourceFile::parse(&*text) | 104 | SourceFile::parse(&*text) |
diff --git a/crates/ra_ide_api/src/completion/completion_context.rs b/crates/ra_ide_api/src/completion/completion_context.rs index f6584cdd6..4aa84751f 100644 --- a/crates/ra_ide_api/src/completion/completion_context.rs +++ b/crates/ra_ide_api/src/completion/completion_context.rs | |||
@@ -43,7 +43,7 @@ pub(crate) struct CompletionContext<'a> { | |||
43 | impl<'a> CompletionContext<'a> { | 43 | impl<'a> CompletionContext<'a> { |
44 | pub(super) fn new( | 44 | pub(super) fn new( |
45 | db: &'a db::RootDatabase, | 45 | db: &'a db::RootDatabase, |
46 | original_parse: &'a Parse, | 46 | original_parse: &'a Parse<ast::SourceFile>, |
47 | position: FilePosition, | 47 | position: FilePosition, |
48 | ) -> Option<CompletionContext<'a>> { | 48 | ) -> Option<CompletionContext<'a>> { |
49 | let module = source_binder::module_from_position(db, position); | 49 | let module = source_binder::module_from_position(db, position); |
@@ -83,7 +83,7 @@ impl<'a> CompletionContext<'a> { | |||
83 | } | 83 | } |
84 | } | 84 | } |
85 | 85 | ||
86 | fn fill(&mut self, original_parse: &'a Parse, offset: TextUnit) { | 86 | fn fill(&mut self, original_parse: &'a Parse<ast::SourceFile>, offset: TextUnit) { |
87 | // Insert a fake ident to get a valid parse tree. We will use this file | 87 | // Insert a fake ident to get a valid parse tree. We will use this file |
88 | // to determine context, though the original_file will be used for | 88 | // to determine context, though the original_file will be used for |
89 | // actual completion. | 89 | // actual completion. |
diff --git a/crates/ra_ide_api/src/status.rs b/crates/ra_ide_api/src/status.rs index ce27f5ae2..d71c89b43 100644 --- a/crates/ra_ide_api/src/status.rs +++ b/crates/ra_ide_api/src/status.rs | |||
@@ -9,7 +9,7 @@ use ra_db::{ | |||
9 | FileTextQuery, SourceRootId, | 9 | FileTextQuery, SourceRootId, |
10 | }; | 10 | }; |
11 | use ra_prof::{memory_usage, Bytes}; | 11 | use ra_prof::{memory_usage, Bytes}; |
12 | use ra_syntax::{AstNode, Parse, SyntaxNode, TreeArc}; | 12 | use ra_syntax::{ast, AstNode, Parse, SyntaxNode, TreeArc}; |
13 | 13 | ||
14 | use crate::{ | 14 | use crate::{ |
15 | db::RootDatabase, | 15 | db::RootDatabase, |
@@ -79,10 +79,10 @@ impl fmt::Display for SyntaxTreeStats { | |||
79 | } | 79 | } |
80 | } | 80 | } |
81 | 81 | ||
82 | impl FromIterator<TableEntry<FileId, Parse>> for SyntaxTreeStats { | 82 | impl FromIterator<TableEntry<FileId, Parse<ast::SourceFile>>> for SyntaxTreeStats { |
83 | fn from_iter<T>(iter: T) -> SyntaxTreeStats | 83 | fn from_iter<T>(iter: T) -> SyntaxTreeStats |
84 | where | 84 | where |
85 | T: IntoIterator<Item = TableEntry<FileId, Parse>>, | 85 | T: IntoIterator<Item = TableEntry<FileId, Parse<ast::SourceFile>>>, |
86 | { | 86 | { |
87 | let mut res = SyntaxTreeStats::default(); | 87 | let mut res = SyntaxTreeStats::default(); |
88 | for entry in iter { | 88 | for entry in iter { |
diff --git a/crates/ra_ide_api/src/symbol_index.rs b/crates/ra_ide_api/src/symbol_index.rs index 1f2ba954e..9b3a45319 100644 --- a/crates/ra_ide_api/src/symbol_index.rs +++ b/crates/ra_ide_api/src/symbol_index.rs | |||
@@ -169,7 +169,9 @@ impl SymbolIndex { | |||
169 | self.map.as_fst().size() + self.symbols.len() * mem::size_of::<FileSymbol>() | 169 | self.map.as_fst().size() + self.symbols.len() * mem::size_of::<FileSymbol>() |
170 | } | 170 | } |
171 | 171 | ||
172 | pub(crate) fn for_files(files: impl ParallelIterator<Item = (FileId, Parse)>) -> SymbolIndex { | 172 | pub(crate) fn for_files( |
173 | files: impl ParallelIterator<Item = (FileId, Parse<ast::SourceFile>)>, | ||
174 | ) -> SymbolIndex { | ||
173 | let symbols = files | 175 | let symbols = files |
174 | .flat_map(|(file_id, file)| source_file_to_file_symbols(file.tree(), file_id)) | 176 | .flat_map(|(file_id, file)| source_file_to_file_symbols(file.tree(), file_id)) |
175 | .collect::<Vec<_>>(); | 177 | .collect::<Vec<_>>(); |
diff --git a/crates/ra_syntax/src/lib.rs b/crates/ra_syntax/src/lib.rs index 0fa2fe382..2eb3fcd57 100644 --- a/crates/ra_syntax/src/lib.rs +++ b/crates/ra_syntax/src/lib.rs | |||
@@ -35,7 +35,7 @@ use std::{fmt::Write, sync::Arc}; | |||
35 | 35 | ||
36 | use ra_text_edit::AtomTextEdit; | 36 | use ra_text_edit::AtomTextEdit; |
37 | 37 | ||
38 | use crate::syntax_node::GreenNode; | 38 | use crate::syntax_node::{GreenNode, SyntaxNodeWrapper}; |
39 | 39 | ||
40 | pub use crate::{ | 40 | pub use crate::{ |
41 | ast::{AstNode, AstToken}, | 41 | ast::{AstNode, AstToken}, |
@@ -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,16 @@ 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 Parse<SourceFile> { |
84 | self.incremental_reparse(edit).unwrap_or_else(|| self.full_reparse(edit)) | ||
85 | } | ||
86 | |||
87 | pub fn debug_dump(&self) -> String { | 95 | pub fn debug_dump(&self) -> String { |
88 | let mut buf = self.tree.syntax().debug_dump(); | 96 | let mut buf = self.tree.syntax().debug_dump(); |
89 | for err in self.errors.iter() { | 97 | for err in self.errors.iter() { |
@@ -92,7 +100,11 @@ impl Parse { | |||
92 | buf | 100 | buf |
93 | } | 101 | } |
94 | 102 | ||
95 | fn incremental_reparse(&self, edit: &AtomTextEdit) -> Option<Parse> { | 103 | pub fn reparse(&self, edit: &AtomTextEdit) -> Parse<SourceFile> { |
104 | self.incremental_reparse(edit).unwrap_or_else(|| self.full_reparse(edit)) | ||
105 | } | ||
106 | |||
107 | fn incremental_reparse(&self, edit: &AtomTextEdit) -> Option<Parse<SourceFile>> { | ||
96 | // FIXME: validation errors are not handled here | 108 | // FIXME: validation errors are not handled here |
97 | parsing::incremental_reparse(self.tree.syntax(), edit, self.errors.to_vec()).map( | 109 | parsing::incremental_reparse(self.tree.syntax(), edit, self.errors.to_vec()).map( |
98 | |(green_node, errors, _reparsed_range)| Parse { | 110 | |(green_node, errors, _reparsed_range)| Parse { |
@@ -102,12 +114,19 @@ impl Parse { | |||
102 | ) | 114 | ) |
103 | } | 115 | } |
104 | 116 | ||
105 | fn full_reparse(&self, edit: &AtomTextEdit) -> Parse { | 117 | fn full_reparse(&self, edit: &AtomTextEdit) -> Parse<SourceFile> { |
106 | let text = edit.apply(self.tree.syntax().text().to_string()); | 118 | let text = edit.apply(self.tree.syntax().text().to_string()); |
107 | SourceFile::parse(&text) | 119 | SourceFile::parse(&text) |
108 | } | 120 | } |
109 | } | 121 | } |
110 | 122 | ||
123 | impl Parse<SyntaxNode> { | ||
124 | pub fn cast<T: AstNode>(self) -> Option<Parse<T>> { | ||
125 | let node = T::cast(&self.tree)?; | ||
126 | Some(Parse { tree: node.to_owned(), errors: self.errors }) | ||
127 | } | ||
128 | } | ||
129 | |||
111 | /// `SourceFile` represents a parse tree for a single Rust file. | 130 | /// `SourceFile` represents a parse tree for a single Rust file. |
112 | pub use crate::ast::SourceFile; | 131 | pub use crate::ast::SourceFile; |
113 | 132 | ||
@@ -121,7 +140,7 @@ impl SourceFile { | |||
121 | TreeArc::cast(root) | 140 | TreeArc::cast(root) |
122 | } | 141 | } |
123 | 142 | ||
124 | pub fn parse(text: &str) -> Parse { | 143 | pub fn parse(text: &str) -> Parse<SourceFile> { |
125 | let (green, mut errors) = parsing::parse_text(text); | 144 | let (green, mut errors) = parsing::parse_text(text); |
126 | let tree = SourceFile::new(green); | 145 | let tree = SourceFile::new(green); |
127 | errors.extend(validation::validate(&tree)); | 146 | errors.extend(validation::validate(&tree)); |