aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_db/src/lib.rs6
-rw-r--r--crates/ra_ide_api/src/completion/completion_context.rs4
-rw-r--r--crates/ra_ide_api/src/status.rs6
-rw-r--r--crates/ra_ide_api/src/symbol_index.rs4
-rw-r--r--crates/ra_syntax/src/lib.rs47
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;
5use std::{panic, sync::Arc}; 5use std::{panic, sync::Arc};
6 6
7use ra_prof::profile; 7use ra_prof::profile;
8use ra_syntax::{Parse, SourceFile, TextRange, TextUnit}; 8use ra_syntax::{ast, Parse, SourceFile, TextRange, TextUnit};
9use relative_path::RelativePathBuf; 9use relative_path::RelativePathBuf;
10 10
11pub use crate::{ 11pub 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
101fn parse_query(db: &impl SourceDatabase, file_id: FileId) -> Parse { 101fn 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> {
43impl<'a> CompletionContext<'a> { 43impl<'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};
11use ra_prof::{memory_usage, Bytes}; 11use ra_prof::{memory_usage, Bytes};
12use ra_syntax::{AstNode, Parse, SyntaxNode, TreeArc}; 12use ra_syntax::{ast, AstNode, Parse, SyntaxNode, TreeArc};
13 13
14use crate::{ 14use crate::{
15 db::RootDatabase, 15 db::RootDatabase,
@@ -79,10 +79,10 @@ impl fmt::Display for SyntaxTreeStats {
79 } 79 }
80} 80}
81 81
82impl FromIterator<TableEntry<FileId, Parse>> for SyntaxTreeStats { 82impl 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
36use ra_text_edit::AtomTextEdit; 36use ra_text_edit::AtomTextEdit;
37 37
38use crate::syntax_node::GreenNode; 38use crate::syntax_node::{GreenNode, SyntaxNodeWrapper};
39 39
40pub use crate::{ 40pub 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)]
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,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 { 94impl 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
123impl 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.
112pub use crate::ast::SourceFile; 131pub 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));