aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2019-07-12 17:42:06 +0100
committerbors[bot] <26634292+bors[bot]@users.noreply.github.com>2019-07-12 17:42:06 +0100
commit8bb81d7418dbc4c295d31d261441b67dba4c0f76 (patch)
treeaf552549d828905294f4f3c109cdc339c12020ad
parent2e466bb365813620de15afd5e04736a92fffdca9 (diff)
parentdeab4caa7b1ba81c1b7e6561bc270bbde6467f13 (diff)
Merge #1524
1524: make Parse fields private r=matklad a=matklad Co-authored-by: Aleksey Kladov <[email protected]>
-rw-r--r--crates/ra_assists/src/assist_ctx.rs4
-rw-r--r--crates/ra_assists/src/ast_editor.rs7
-rw-r--r--crates/ra_cli/src/main.rs2
-rw-r--r--crates/ra_hir/src/code_model.rs2
-rw-r--r--crates/ra_hir/src/expr/validation.rs3
-rw-r--r--crates/ra_hir/src/ids.rs2
-rw-r--r--crates/ra_hir/src/source_binder.rs4
-rw-r--r--crates/ra_ide_api/src/call_info.rs4
-rw-r--r--crates/ra_ide_api/src/change.rs4
-rw-r--r--crates/ra_ide_api/src/completion/completion_context.rs6
-rw-r--r--crates/ra_ide_api/src/diagnostics.rs12
-rw-r--r--crates/ra_ide_api/src/display/navigation_target.rs12
-rw-r--r--crates/ra_ide_api/src/extend_selection.rs8
-rw-r--r--crates/ra_ide_api/src/folding_ranges.rs4
-rw-r--r--crates/ra_ide_api/src/goto_definition.rs4
-rw-r--r--crates/ra_ide_api/src/goto_type_definition.rs4
-rw-r--r--crates/ra_ide_api/src/hover.rs7
-rw-r--r--crates/ra_ide_api/src/impls.rs4
-rw-r--r--crates/ra_ide_api/src/join_lines.rs4
-rw-r--r--crates/ra_ide_api/src/lib.rs20
-rw-r--r--crates/ra_ide_api/src/matching_brace.rs4
-rw-r--r--crates/ra_ide_api/src/references.rs8
-rw-r--r--crates/ra_ide_api/src/runnables.rs4
-rw-r--r--crates/ra_ide_api/src/status.rs2
-rw-r--r--crates/ra_ide_api/src/symbol_index.rs14
-rw-r--r--crates/ra_ide_api/src/syntax_highlighting.rs16
-rw-r--r--crates/ra_ide_api/src/syntax_tree.rs10
-rw-r--r--crates/ra_ide_api/src/typing.rs13
-rw-r--r--crates/ra_mbe/src/tests.rs4
-rw-r--r--crates/ra_syntax/src/lib.rs12
-rw-r--r--crates/ra_syntax/tests/test.rs4
31 files changed, 109 insertions, 99 deletions
diff --git a/crates/ra_assists/src/assist_ctx.rs b/crates/ra_assists/src/assist_ctx.rs
index 0ba5f3ae6..34b207154 100644
--- a/crates/ra_assists/src/assist_ctx.rs
+++ b/crates/ra_assists/src/assist_ctx.rs
@@ -71,11 +71,11 @@ impl<'a, DB: HirDatabase> AssistCtx<'a, DB> {
71 where 71 where
72 F: FnOnce(AssistCtx<DB>) -> T, 72 F: FnOnce(AssistCtx<DB>) -> T,
73 { 73 {
74 let source_file = &db.parse(frange.file_id).tree; 74 let parse = db.parse(frange.file_id);
75 let assist = 75 let assist =
76 if should_compute_edit { Assist::Resolved(vec![]) } else { Assist::Unresolved(vec![]) }; 76 if should_compute_edit { Assist::Resolved(vec![]) } else { Assist::Unresolved(vec![]) };
77 77
78 let ctx = AssistCtx { db, frange, source_file, should_compute_edit, assist }; 78 let ctx = AssistCtx { db, frange, source_file: parse.tree(), should_compute_edit, assist };
79 f(ctx) 79 f(ctx)
80 } 80 }
81 81
diff --git a/crates/ra_assists/src/ast_editor.rs b/crates/ra_assists/src/ast_editor.rs
index ba816eb65..7b743c9f0 100644
--- a/crates/ra_assists/src/ast_editor.rs
+++ b/crates/ra_assists/src/ast_editor.rs
@@ -278,8 +278,8 @@ impl AstBuilder<ast::NameRef> {
278} 278}
279 279
280fn ast_node_from_file_text<N: AstNode>(text: &str) -> TreeArc<N> { 280fn ast_node_from_file_text<N: AstNode>(text: &str) -> TreeArc<N> {
281 let file = SourceFile::parse(text).tree; 281 let parse = SourceFile::parse(text);
282 let res = file.syntax().descendants().find_map(N::cast).unwrap().to_owned(); 282 let res = parse.tree().syntax().descendants().find_map(N::cast).unwrap().to_owned();
283 res 283 res
284} 284}
285 285
@@ -287,7 +287,8 @@ mod tokens {
287 use once_cell::sync::Lazy; 287 use once_cell::sync::Lazy;
288 use ra_syntax::{AstNode, SourceFile, SyntaxKind::*, SyntaxToken, TreeArc, T}; 288 use ra_syntax::{AstNode, SourceFile, SyntaxKind::*, SyntaxToken, TreeArc, T};
289 289
290 static SOURCE_FILE: Lazy<TreeArc<SourceFile>> = Lazy::new(|| SourceFile::parse(",\n; ;").tree); 290 static SOURCE_FILE: Lazy<TreeArc<SourceFile>> =
291 Lazy::new(|| SourceFile::parse(",\n; ;").tree().to_owned());
291 292
292 pub(crate) fn comma() -> SyntaxToken<'static> { 293 pub(crate) fn comma() -> SyntaxToken<'static> {
293 SOURCE_FILE 294 SOURCE_FILE
diff --git a/crates/ra_cli/src/main.rs b/crates/ra_cli/src/main.rs
index 48bc64450..b063193cf 100644
--- a/crates/ra_cli/src/main.rs
+++ b/crates/ra_cli/src/main.rs
@@ -102,7 +102,7 @@ fn main() -> Result<()> {
102 102
103fn file() -> Result<TreeArc<SourceFile>> { 103fn file() -> Result<TreeArc<SourceFile>> {
104 let text = read_stdin()?; 104 let text = read_stdin()?;
105 Ok(SourceFile::parse(&text).tree) 105 Ok(SourceFile::parse(&text).tree().to_owned())
106} 106}
107 107
108fn read_stdin() -> Result<String> { 108fn read_stdin() -> Result<String> {
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs
index 805357662..4fb5844f4 100644
--- a/crates/ra_hir/src/code_model.rs
+++ b/crates/ra_hir/src/code_model.rs
@@ -167,7 +167,7 @@ impl ModuleSource {
167 ) -> ModuleSource { 167 ) -> ModuleSource {
168 match (file_id, decl_id) { 168 match (file_id, decl_id) {
169 (Some(file_id), _) => { 169 (Some(file_id), _) => {
170 let source_file = db.parse(file_id).tree; 170 let source_file = db.parse(file_id).tree().to_owned();
171 ModuleSource::SourceFile(source_file) 171 ModuleSource::SourceFile(source_file)
172 } 172 }
173 (None, Some(item_id)) => { 173 (None, Some(item_id)) => {
diff --git a/crates/ra_hir/src/expr/validation.rs b/crates/ra_hir/src/expr/validation.rs
index 4e6131dce..c2a10a0b5 100644
--- a/crates/ra_hir/src/expr/validation.rs
+++ b/crates/ra_hir/src/expr/validation.rs
@@ -71,7 +71,8 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
71 } 71 }
72 let source_map = self.func.body_source_map(db); 72 let source_map = self.func.body_source_map(db);
73 let file_id = self.func.source(db).file_id; 73 let file_id = self.func.source(db).file_id;
74 let source_file = db.parse(file_id.original_file(db)).tree; 74 let parse = db.parse(file_id.original_file(db));
75 let source_file = parse.tree();
75 if let Some(field_list_node) = source_map 76 if let Some(field_list_node) = source_map
76 .expr_syntax(id) 77 .expr_syntax(id)
77 .map(|ptr| ptr.to_node(source_file.syntax())) 78 .map(|ptr| ptr.to_node(source_file.syntax()))
diff --git a/crates/ra_hir/src/ids.rs b/crates/ra_hir/src/ids.rs
index 5212b78ac..80e9cccd6 100644
--- a/crates/ra_hir/src/ids.rs
+++ b/crates/ra_hir/src/ids.rs
@@ -60,7 +60,7 @@ impl HirFileId {
60 file_id: HirFileId, 60 file_id: HirFileId,
61 ) -> Option<TreeArc<SyntaxNode>> { 61 ) -> Option<TreeArc<SyntaxNode>> {
62 match file_id.0 { 62 match file_id.0 {
63 HirFileIdRepr::File(file_id) => Some(db.parse(file_id).tree.syntax().to_owned()), 63 HirFileIdRepr::File(file_id) => Some(db.parse(file_id).tree().syntax().to_owned()),
64 HirFileIdRepr::Macro(macro_file) => db.parse_macro(macro_file), 64 HirFileIdRepr::Macro(macro_file) => db.parse_macro(macro_file),
65 } 65 }
66 } 66 }
diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs
index 429575fee..573add7da 100644
--- a/crates/ra_hir/src/source_binder.rs
+++ b/crates/ra_hir/src/source_binder.rs
@@ -49,8 +49,8 @@ pub fn module_from_declaration(
49 49
50/// Locates the module by position in the source code. 50/// Locates the module by position in the source code.
51pub fn module_from_position(db: &impl HirDatabase, position: FilePosition) -> Option<Module> { 51pub fn module_from_position(db: &impl HirDatabase, position: FilePosition) -> Option<Module> {
52 let file = db.parse(position.file_id).tree; 52 let parse = db.parse(position.file_id);
53 match find_node_at_offset::<ast::Module>(file.syntax(), position.offset) { 53 match find_node_at_offset::<ast::Module>(parse.tree().syntax(), position.offset) {
54 Some(m) if !m.has_semi() => module_from_inline(db, position.file_id, m), 54 Some(m) if !m.has_semi() => module_from_inline(db, position.file_id, m),
55 _ => module_from_file_id(db, position.file_id), 55 _ => module_from_file_id(db, position.file_id),
56 } 56 }
diff --git a/crates/ra_ide_api/src/call_info.rs b/crates/ra_ide_api/src/call_info.rs
index 368fdcaa1..11dea7c14 100644
--- a/crates/ra_ide_api/src/call_info.rs
+++ b/crates/ra_ide_api/src/call_info.rs
@@ -10,8 +10,8 @@ use crate::{db::RootDatabase, CallInfo, FilePosition, FunctionSignature};
10 10
11/// Computes parameter information for the given call expression. 11/// Computes parameter information for the given call expression.
12pub(crate) fn call_info(db: &RootDatabase, position: FilePosition) -> Option<CallInfo> { 12pub(crate) fn call_info(db: &RootDatabase, position: FilePosition) -> Option<CallInfo> {
13 let file = db.parse(position.file_id).tree; 13 let parse = db.parse(position.file_id);
14 let syntax = file.syntax(); 14 let syntax = parse.tree().syntax();
15 15
16 // Find the calling expression and it's NameRef 16 // Find the calling expression and it's NameRef
17 let calling_node = FnCallNode::with_node(syntax, position.offset)?; 17 let calling_node = FnCallNode::with_node(syntax, position.offset)?;
diff --git a/crates/ra_ide_api/src/change.rs b/crates/ra_ide_api/src/change.rs
index 179f17ca4..1ba818197 100644
--- a/crates/ra_ide_api/src/change.rs
+++ b/crates/ra_ide_api/src/change.rs
@@ -135,8 +135,8 @@ impl LibraryData {
135 files: Vec<(FileId, RelativePathBuf, Arc<String>)>, 135 files: Vec<(FileId, RelativePathBuf, Arc<String>)>,
136 ) -> LibraryData { 136 ) -> LibraryData {
137 let symbol_index = SymbolIndex::for_files(files.par_iter().map(|(file_id, _, text)| { 137 let symbol_index = SymbolIndex::for_files(files.par_iter().map(|(file_id, _, text)| {
138 let file = SourceFile::parse(text).tree; 138 let parse = SourceFile::parse(text);
139 (*file_id, file) 139 (*file_id, parse)
140 })); 140 }));
141 let mut root_change = RootChange::default(); 141 let mut root_change = RootChange::default();
142 root_change.added = files 142 root_change.added = files
diff --git a/crates/ra_ide_api/src/completion/completion_context.rs b/crates/ra_ide_api/src/completion/completion_context.rs
index 55fdba50d..f6584cdd6 100644
--- a/crates/ra_ide_api/src/completion/completion_context.rs
+++ b/crates/ra_ide_api/src/completion/completion_context.rs
@@ -48,7 +48,7 @@ impl<'a> CompletionContext<'a> {
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);
50 let token = 50 let token =
51 find_token_at_offset(original_parse.tree.syntax(), position.offset).left_biased()?; 51 find_token_at_offset(original_parse.tree().syntax(), position.offset).left_biased()?;
52 let analyzer = 52 let analyzer =
53 hir::SourceAnalyzer::new(db, position.file_id, token.parent(), Some(position.offset)); 53 hir::SourceAnalyzer::new(db, position.file_id, token.parent(), Some(position.offset));
54 let mut ctx = CompletionContext { 54 let mut ctx = CompletionContext {
@@ -89,7 +89,7 @@ impl<'a> CompletionContext<'a> {
89 // actual completion. 89 // actual completion.
90 let file = { 90 let file = {
91 let edit = AtomTextEdit::insert(offset, "intellijRulezz".to_string()); 91 let edit = AtomTextEdit::insert(offset, "intellijRulezz".to_string());
92 original_parse.reparse(&edit).tree 92 original_parse.reparse(&edit).tree().to_owned()
93 }; 93 };
94 94
95 // First, let's try to complete a reference to some declaration. 95 // First, let's try to complete a reference to some declaration.
@@ -100,7 +100,7 @@ impl<'a> CompletionContext<'a> {
100 self.is_param = true; 100 self.is_param = true;
101 return; 101 return;
102 } 102 }
103 self.classify_name_ref(&original_parse.tree, name_ref); 103 self.classify_name_ref(original_parse.tree(), name_ref);
104 } 104 }
105 105
106 // Otherwise, see if this is a declaration. We can use heuristics to 106 // Otherwise, see if this is a declaration. We can use heuristics to
diff --git a/crates/ra_ide_api/src/diagnostics.rs b/crates/ra_ide_api/src/diagnostics.rs
index a46289cba..3f5b9e0a0 100644
--- a/crates/ra_ide_api/src/diagnostics.rs
+++ b/crates/ra_ide_api/src/diagnostics.rs
@@ -27,14 +27,14 @@ pub(crate) fn diagnostics(db: &RootDatabase, file_id: FileId) -> Vec<Diagnostic>
27 let parse = db.parse(file_id); 27 let parse = db.parse(file_id);
28 let mut res = Vec::new(); 28 let mut res = Vec::new();
29 29
30 res.extend(parse.errors.iter().map(|err| Diagnostic { 30 res.extend(parse.errors().iter().map(|err| Diagnostic {
31 range: location_to_range(err.location()), 31 range: location_to_range(err.location()),
32 message: format!("Syntax Error: {}", err), 32 message: format!("Syntax Error: {}", err),
33 severity: Severity::Error, 33 severity: Severity::Error,
34 fix: None, 34 fix: None,
35 })); 35 }));
36 36
37 for node in parse.tree.syntax().descendants() { 37 for node in parse.tree().syntax().descendants() {
38 check_unnecessary_braces_in_use_statement(&mut res, file_id, node); 38 check_unnecessary_braces_in_use_statement(&mut res, file_id, node);
39 check_struct_shorthand_initialization(&mut res, file_id, node); 39 check_struct_shorthand_initialization(&mut res, file_id, node);
40 } 40 }
@@ -181,18 +181,18 @@ mod tests {
181 type DiagnosticChecker = fn(&mut Vec<Diagnostic>, FileId, &SyntaxNode) -> Option<()>; 181 type DiagnosticChecker = fn(&mut Vec<Diagnostic>, FileId, &SyntaxNode) -> Option<()>;
182 182
183 fn check_not_applicable(code: &str, func: DiagnosticChecker) { 183 fn check_not_applicable(code: &str, func: DiagnosticChecker) {
184 let file = SourceFile::parse(code).tree; 184 let parse = SourceFile::parse(code);
185 let mut diagnostics = Vec::new(); 185 let mut diagnostics = Vec::new();
186 for node in file.syntax().descendants() { 186 for node in parse.tree().syntax().descendants() {
187 func(&mut diagnostics, FileId(0), node); 187 func(&mut diagnostics, FileId(0), node);
188 } 188 }
189 assert!(diagnostics.is_empty()); 189 assert!(diagnostics.is_empty());
190 } 190 }
191 191
192 fn check_apply(before: &str, after: &str, func: DiagnosticChecker) { 192 fn check_apply(before: &str, after: &str, func: DiagnosticChecker) {
193 let file = SourceFile::parse(before).tree; 193 let parse = SourceFile::parse(before);
194 let mut diagnostics = Vec::new(); 194 let mut diagnostics = Vec::new();
195 for node in file.syntax().descendants() { 195 for node in parse.tree().syntax().descendants() {
196 func(&mut diagnostics, FileId(0), node); 196 func(&mut diagnostics, FileId(0), node);
197 } 197 }
198 let diagnostic = 198 let diagnostic =
diff --git a/crates/ra_ide_api/src/display/navigation_target.rs b/crates/ra_ide_api/src/display/navigation_target.rs
index 1edb64e3d..20a8d418e 100644
--- a/crates/ra_ide_api/src/display/navigation_target.rs
+++ b/crates/ra_ide_api/src/display/navigation_target.rs
@@ -93,8 +93,8 @@ impl NavigationTarget {
93 file_id: FileId, 93 file_id: FileId,
94 pat: AstPtr<ast::Pat>, 94 pat: AstPtr<ast::Pat>,
95 ) -> NavigationTarget { 95 ) -> NavigationTarget {
96 let file = db.parse(file_id).tree; 96 let parse = db.parse(file_id);
97 let (name, full_range) = match pat.to_node(file.syntax()).kind() { 97 let (name, full_range) = match pat.to_node(parse.tree().syntax()).kind() {
98 ast::PatKind::BindPat(pat) => return NavigationTarget::from_bind_pat(file_id, &pat), 98 ast::PatKind::BindPat(pat) => return NavigationTarget::from_bind_pat(file_id, &pat),
99 _ => ("_".into(), pat.syntax_node_ptr().range()), 99 _ => ("_".into(), pat.syntax_node_ptr().range()),
100 }; 100 };
@@ -315,8 +315,8 @@ impl NavigationTarget {
315} 315}
316 316
317pub(crate) fn docs_from_symbol(db: &RootDatabase, symbol: &FileSymbol) -> Option<String> { 317pub(crate) fn docs_from_symbol(db: &RootDatabase, symbol: &FileSymbol) -> Option<String> {
318 let file = db.parse(symbol.file_id).tree; 318 let parse = db.parse(symbol.file_id);
319 let node = symbol.ptr.to_node(file.syntax()).to_owned(); 319 let node = symbol.ptr.to_node(parse.tree().syntax()).to_owned();
320 320
321 fn doc_comments<N: ast::DocCommentsOwner>(node: &N) -> Option<String> { 321 fn doc_comments<N: ast::DocCommentsOwner>(node: &N) -> Option<String> {
322 node.doc_comment_text() 322 node.doc_comment_text()
@@ -341,8 +341,8 @@ pub(crate) fn docs_from_symbol(db: &RootDatabase, symbol: &FileSymbol) -> Option
341/// 341///
342/// e.g. `struct Name`, `enum Name`, `fn Name` 342/// e.g. `struct Name`, `enum Name`, `fn Name`
343pub(crate) fn description_from_symbol(db: &RootDatabase, symbol: &FileSymbol) -> Option<String> { 343pub(crate) fn description_from_symbol(db: &RootDatabase, symbol: &FileSymbol) -> Option<String> {
344 let file = db.parse(symbol.file_id).tree; 344 let parse = db.parse(symbol.file_id);
345 let node = symbol.ptr.to_node(file.syntax()).to_owned(); 345 let node = symbol.ptr.to_node(parse.tree().syntax()).to_owned();
346 346
347 visitor() 347 visitor()
348 .visit(|node: &ast::FnDef| node.short_label()) 348 .visit(|node: &ast::FnDef| node.short_label())
diff --git a/crates/ra_ide_api/src/extend_selection.rs b/crates/ra_ide_api/src/extend_selection.rs
index 655852514..491b15702 100644
--- a/crates/ra_ide_api/src/extend_selection.rs
+++ b/crates/ra_ide_api/src/extend_selection.rs
@@ -11,8 +11,8 @@ use crate::{db::RootDatabase, FileRange};
11 11
12// FIXME: restore macro support 12// FIXME: restore macro support
13pub(crate) fn extend_selection(db: &RootDatabase, frange: FileRange) -> TextRange { 13pub(crate) fn extend_selection(db: &RootDatabase, frange: FileRange) -> TextRange {
14 let source_file = db.parse(frange.file_id).tree; 14 let parse = db.parse(frange.file_id);
15 try_extend_selection(source_file.syntax(), frange.range).unwrap_or(frange.range) 15 try_extend_selection(parse.tree().syntax(), frange.range).unwrap_or(frange.range)
16} 16}
17 17
18fn try_extend_selection(root: &SyntaxNode, range: TextRange) -> Option<TextRange> { 18fn try_extend_selection(root: &SyntaxNode, range: TextRange) -> Option<TextRange> {
@@ -212,10 +212,10 @@ mod tests {
212 212
213 fn do_check(before: &str, afters: &[&str]) { 213 fn do_check(before: &str, afters: &[&str]) {
214 let (cursor, before) = extract_offset(before); 214 let (cursor, before) = extract_offset(before);
215 let file = SourceFile::parse(&before).tree; 215 let parse = SourceFile::parse(&before);
216 let mut range = TextRange::offset_len(cursor, 0.into()); 216 let mut range = TextRange::offset_len(cursor, 0.into());
217 for &after in afters { 217 for &after in afters {
218 range = try_extend_selection(file.syntax(), range).unwrap(); 218 range = try_extend_selection(parse.tree().syntax(), range).unwrap();
219 let actual = &before[range]; 219 let actual = &before[range];
220 assert_eq!(after, actual); 220 assert_eq!(after, actual);
221 } 221 }
diff --git a/crates/ra_ide_api/src/folding_ranges.rs b/crates/ra_ide_api/src/folding_ranges.rs
index a1e6f94e0..9d4855a64 100644
--- a/crates/ra_ide_api/src/folding_ranges.rs
+++ b/crates/ra_ide_api/src/folding_ranges.rs
@@ -192,8 +192,8 @@ mod tests {
192 192
193 fn do_check(text: &str, fold_kinds: &[FoldKind]) { 193 fn do_check(text: &str, fold_kinds: &[FoldKind]) {
194 let (ranges, text) = extract_ranges(text, "fold"); 194 let (ranges, text) = extract_ranges(text, "fold");
195 let file = SourceFile::parse(&text).tree; 195 let parse = SourceFile::parse(&text);
196 let folds = folding_ranges(&file); 196 let folds = folding_ranges(parse.tree());
197 197
198 assert_eq!( 198 assert_eq!(
199 folds.len(), 199 folds.len(),
diff --git a/crates/ra_ide_api/src/goto_definition.rs b/crates/ra_ide_api/src/goto_definition.rs
index 08feed7dc..1066bf155 100644
--- a/crates/ra_ide_api/src/goto_definition.rs
+++ b/crates/ra_ide_api/src/goto_definition.rs
@@ -19,8 +19,8 @@ pub(crate) fn goto_definition(
19 db: &RootDatabase, 19 db: &RootDatabase,
20 position: FilePosition, 20 position: FilePosition,
21) -> Option<RangeInfo<Vec<NavigationTarget>>> { 21) -> Option<RangeInfo<Vec<NavigationTarget>>> {
22 let file = db.parse(position.file_id).tree; 22 let parse = db.parse(position.file_id);
23 let syntax = file.syntax(); 23 let syntax = parse.tree().syntax();
24 if let Some(name_ref) = find_node_at_offset::<ast::NameRef>(syntax, position.offset) { 24 if let Some(name_ref) = find_node_at_offset::<ast::NameRef>(syntax, position.offset) {
25 let navs = reference_definition(db, position.file_id, name_ref).to_vec(); 25 let navs = reference_definition(db, position.file_id, name_ref).to_vec();
26 return Some(RangeInfo::new(name_ref.syntax().range(), navs.to_vec())); 26 return Some(RangeInfo::new(name_ref.syntax().range(), navs.to_vec()));
diff --git a/crates/ra_ide_api/src/goto_type_definition.rs b/crates/ra_ide_api/src/goto_type_definition.rs
index d2d5eae9a..6ce5e214f 100644
--- a/crates/ra_ide_api/src/goto_type_definition.rs
+++ b/crates/ra_ide_api/src/goto_type_definition.rs
@@ -7,9 +7,9 @@ pub(crate) fn goto_type_definition(
7 db: &RootDatabase, 7 db: &RootDatabase,
8 position: FilePosition, 8 position: FilePosition,
9) -> Option<RangeInfo<Vec<NavigationTarget>>> { 9) -> Option<RangeInfo<Vec<NavigationTarget>>> {
10 let file = db.parse(position.file_id).tree; 10 let parse = db.parse(position.file_id);
11 11
12 let node = find_token_at_offset(file.syntax(), position.offset).find_map(|token| { 12 let node = find_token_at_offset(parse.tree().syntax(), position.offset).find_map(|token| {
13 token 13 token
14 .parent() 14 .parent()
15 .ancestors() 15 .ancestors()
diff --git a/crates/ra_ide_api/src/hover.rs b/crates/ra_ide_api/src/hover.rs
index 48f1f49c9..253d21f48 100644
--- a/crates/ra_ide_api/src/hover.rs
+++ b/crates/ra_ide_api/src/hover.rs
@@ -94,7 +94,8 @@ fn hover_text(docs: Option<String>, desc: Option<String>) -> Option<String> {
94} 94}
95 95
96pub(crate) fn hover(db: &RootDatabase, position: FilePosition) -> Option<RangeInfo<HoverResult>> { 96pub(crate) fn hover(db: &RootDatabase, position: FilePosition) -> Option<RangeInfo<HoverResult>> {
97 let file = db.parse(position.file_id).tree; 97 let parse = db.parse(position.file_id);
98 let file = parse.tree();
98 let mut res = HoverResult::new(); 99 let mut res = HoverResult::new();
99 100
100 let mut range = None; 101 let mut range = None;
@@ -241,8 +242,8 @@ pub(crate) fn hover(db: &RootDatabase, position: FilePosition) -> Option<RangeIn
241} 242}
242 243
243pub(crate) fn type_of(db: &RootDatabase, frange: FileRange) -> Option<String> { 244pub(crate) fn type_of(db: &RootDatabase, frange: FileRange) -> Option<String> {
244 let file = db.parse(frange.file_id).tree; 245 let parse = db.parse(frange.file_id);
245 let syntax = file.syntax(); 246 let syntax = parse.tree().syntax();
246 let leaf_node = find_covering_element(syntax, frange.range); 247 let leaf_node = find_covering_element(syntax, frange.range);
247 // if we picked identifier, expand to pattern/expression 248 // if we picked identifier, expand to pattern/expression
248 let node = leaf_node 249 let node = leaf_node
diff --git a/crates/ra_ide_api/src/impls.rs b/crates/ra_ide_api/src/impls.rs
index 97615b01f..6d69f36aa 100644
--- a/crates/ra_ide_api/src/impls.rs
+++ b/crates/ra_ide_api/src/impls.rs
@@ -8,8 +8,8 @@ pub(crate) fn goto_implementation(
8 db: &RootDatabase, 8 db: &RootDatabase,
9 position: FilePosition, 9 position: FilePosition,
10) -> Option<RangeInfo<Vec<NavigationTarget>>> { 10) -> Option<RangeInfo<Vec<NavigationTarget>>> {
11 let file = db.parse(position.file_id).tree; 11 let parse = db.parse(position.file_id);
12 let syntax = file.syntax(); 12 let syntax = parse.tree().syntax();
13 13
14 let module = source_binder::module_from_position(db, position)?; 14 let module = source_binder::module_from_position(db, position)?;
15 15
diff --git a/crates/ra_ide_api/src/join_lines.rs b/crates/ra_ide_api/src/join_lines.rs
index 8ab485adb..e20cb1370 100644
--- a/crates/ra_ide_api/src/join_lines.rs
+++ b/crates/ra_ide_api/src/join_lines.rs
@@ -503,8 +503,8 @@ fn foo() {
503 503
504 fn check_join_lines_sel(before: &str, after: &str) { 504 fn check_join_lines_sel(before: &str, after: &str) {
505 let (sel, before) = extract_range(before); 505 let (sel, before) = extract_range(before);
506 let file = SourceFile::parse(&before).tree; 506 let parse = SourceFile::parse(&before);
507 let result = join_lines(&file, sel); 507 let result = join_lines(parse.tree(), sel);
508 let actual = result.apply(&before); 508 let actual = result.apply(&before);
509 assert_eq_text!(after, &actual); 509 assert_eq_text!(after, &actual);
510 } 510 }
diff --git a/crates/ra_ide_api/src/lib.rs b/crates/ra_ide_api/src/lib.rs
index 95de9bcb8..9f3b18d9d 100644
--- a/crates/ra_ide_api/src/lib.rs
+++ b/crates/ra_ide_api/src/lib.rs
@@ -326,7 +326,7 @@ impl Analysis {
326 326
327 /// Gets the syntax tree of the file. 327 /// Gets the syntax tree of the file.
328 pub fn parse(&self, file_id: FileId) -> TreeArc<SourceFile> { 328 pub fn parse(&self, file_id: FileId) -> TreeArc<SourceFile> {
329 self.db.parse(file_id).tree 329 self.db.parse(file_id).tree().to_owned()
330 } 330 }
331 331
332 /// Gets the file's `LineIndex`: data structure to convert between absolute 332 /// Gets the file's `LineIndex`: data structure to convert between absolute
@@ -343,7 +343,8 @@ impl Analysis {
343 /// Returns position of the matching brace (all types of braces are 343 /// Returns position of the matching brace (all types of braces are
344 /// supported). 344 /// supported).
345 pub fn matching_brace(&self, position: FilePosition) -> Option<TextUnit> { 345 pub fn matching_brace(&self, position: FilePosition) -> Option<TextUnit> {
346 let file = self.db.parse(position.file_id).tree; 346 let parse = self.db.parse(position.file_id);
347 let file = parse.tree();
347 matching_brace::matching_brace(&file, position.offset) 348 matching_brace::matching_brace(&file, position.offset)
348 } 349 }
349 350
@@ -356,10 +357,10 @@ impl Analysis {
356 /// Returns an edit to remove all newlines in the range, cleaning up minor 357 /// Returns an edit to remove all newlines in the range, cleaning up minor
357 /// stuff like trailing commas. 358 /// stuff like trailing commas.
358 pub fn join_lines(&self, frange: FileRange) -> SourceChange { 359 pub fn join_lines(&self, frange: FileRange) -> SourceChange {
359 let file = self.db.parse(frange.file_id).tree; 360 let parse = self.db.parse(frange.file_id);
360 let file_edit = SourceFileEdit { 361 let file_edit = SourceFileEdit {
361 file_id: frange.file_id, 362 file_id: frange.file_id,
362 edit: join_lines::join_lines(&file, frange.range), 363 edit: join_lines::join_lines(parse.tree(), frange.range),
363 }; 364 };
364 SourceChange::source_file_edit("join lines", file_edit) 365 SourceChange::source_file_edit("join lines", file_edit)
365 } 366 }
@@ -374,7 +375,8 @@ impl Analysis {
374 /// this works when adding `let =`. 375 /// this works when adding `let =`.
375 // FIXME: use a snippet completion instead of this hack here. 376 // FIXME: use a snippet completion instead of this hack here.
376 pub fn on_eq_typed(&self, position: FilePosition) -> Option<SourceChange> { 377 pub fn on_eq_typed(&self, position: FilePosition) -> Option<SourceChange> {
377 let file = self.db.parse(position.file_id).tree; 378 let parse = self.db.parse(position.file_id);
379 let file = parse.tree();
378 let edit = typing::on_eq_typed(&file, position.offset)?; 380 let edit = typing::on_eq_typed(&file, position.offset)?;
379 Some(SourceChange::source_file_edit( 381 Some(SourceChange::source_file_edit(
380 "add semicolon", 382 "add semicolon",
@@ -390,14 +392,14 @@ impl Analysis {
390 /// Returns a tree representation of symbols in the file. Useful to draw a 392 /// Returns a tree representation of symbols in the file. Useful to draw a
391 /// file outline. 393 /// file outline.
392 pub fn file_structure(&self, file_id: FileId) -> Vec<StructureNode> { 394 pub fn file_structure(&self, file_id: FileId) -> Vec<StructureNode> {
393 let file = self.db.parse(file_id).tree; 395 let parse = self.db.parse(file_id);
394 file_structure(&file) 396 file_structure(parse.tree())
395 } 397 }
396 398
397 /// Returns the set of folding ranges. 399 /// Returns the set of folding ranges.
398 pub fn folding_ranges(&self, file_id: FileId) -> Vec<Fold> { 400 pub fn folding_ranges(&self, file_id: FileId) -> Vec<Fold> {
399 let file = self.db.parse(file_id).tree; 401 let parse = self.db.parse(file_id);
400 folding_ranges::folding_ranges(&file) 402 folding_ranges::folding_ranges(parse.tree())
401 } 403 }
402 404
403 /// Fuzzy searches for a symbol. 405 /// Fuzzy searches for a symbol.
diff --git a/crates/ra_ide_api/src/matching_brace.rs b/crates/ra_ide_api/src/matching_brace.rs
index 438b07896..455a5c891 100644
--- a/crates/ra_ide_api/src/matching_brace.rs
+++ b/crates/ra_ide_api/src/matching_brace.rs
@@ -25,8 +25,8 @@ mod tests {
25 fn test_matching_brace() { 25 fn test_matching_brace() {
26 fn do_check(before: &str, after: &str) { 26 fn do_check(before: &str, after: &str) {
27 let (pos, before) = extract_offset(before); 27 let (pos, before) = extract_offset(before);
28 let file = SourceFile::parse(&before).tree; 28 let parse = SourceFile::parse(&before);
29 let new_pos = match matching_brace(&file, pos) { 29 let new_pos = match matching_brace(parse.tree(), pos) {
30 None => pos, 30 None => pos,
31 Some(pos) => pos, 31 Some(pos) => pos,
32 }; 32 };
diff --git a/crates/ra_ide_api/src/references.rs b/crates/ra_ide_api/src/references.rs
index 766c0ad74..0af1ae811 100644
--- a/crates/ra_ide_api/src/references.rs
+++ b/crates/ra_ide_api/src/references.rs
@@ -49,8 +49,8 @@ pub(crate) fn find_all_refs(
49 db: &RootDatabase, 49 db: &RootDatabase,
50 position: FilePosition, 50 position: FilePosition,
51) -> Option<ReferenceSearchResult> { 51) -> Option<ReferenceSearchResult> {
52 let file = db.parse(position.file_id).tree; 52 let parse = db.parse(position.file_id);
53 let (binding, analyzer) = find_binding(db, &file, position)?; 53 let (binding, analyzer) = find_binding(db, parse.tree(), position)?;
54 let declaration = NavigationTarget::from_bind_pat(position.file_id, binding); 54 let declaration = NavigationTarget::from_bind_pat(position.file_id, binding);
55 55
56 let references = analyzer 56 let references = analyzer
@@ -88,8 +88,8 @@ pub(crate) fn rename(
88 position: FilePosition, 88 position: FilePosition,
89 new_name: &str, 89 new_name: &str,
90) -> Option<SourceChange> { 90) -> Option<SourceChange> {
91 let source_file = db.parse(position.file_id).tree; 91 let parse = db.parse(position.file_id);
92 let syntax = source_file.syntax(); 92 let syntax = parse.tree().syntax();
93 93
94 if let Some((ast_name, ast_module)) = find_name_and_module_at_offset(syntax, position) { 94 if let Some((ast_name, ast_module)) = find_name_and_module_at_offset(syntax, position) {
95 rename_mod(db, ast_name, ast_module, position, new_name) 95 rename_mod(db, ast_name, ast_module, position, new_name)
diff --git a/crates/ra_ide_api/src/runnables.rs b/crates/ra_ide_api/src/runnables.rs
index 2d2d0b40e..8cb859b37 100644
--- a/crates/ra_ide_api/src/runnables.rs
+++ b/crates/ra_ide_api/src/runnables.rs
@@ -22,8 +22,8 @@ pub enum RunnableKind {
22} 22}
23 23
24pub(crate) fn runnables(db: &RootDatabase, file_id: FileId) -> Vec<Runnable> { 24pub(crate) fn runnables(db: &RootDatabase, file_id: FileId) -> Vec<Runnable> {
25 let source_file = db.parse(file_id).tree; 25 let parse = db.parse(file_id);
26 source_file.syntax().descendants().filter_map(|i| runnable(db, file_id, i)).collect() 26 parse.tree().syntax().descendants().filter_map(|i| runnable(db, file_id, i)).collect()
27} 27}
28 28
29fn runnable(db: &RootDatabase, file_id: FileId, item: &SyntaxNode) -> Option<Runnable> { 29fn runnable(db: &RootDatabase, file_id: FileId, item: &SyntaxNode) -> Option<Runnable> {
diff --git a/crates/ra_ide_api/src/status.rs b/crates/ra_ide_api/src/status.rs
index 1bcba0b8b..ce27f5ae2 100644
--- a/crates/ra_ide_api/src/status.rs
+++ b/crates/ra_ide_api/src/status.rs
@@ -87,7 +87,7 @@ impl FromIterator<TableEntry<FileId, Parse>> for SyntaxTreeStats {
87 let mut res = SyntaxTreeStats::default(); 87 let mut res = SyntaxTreeStats::default();
88 for entry in iter { 88 for entry in iter {
89 res.total += 1; 89 res.total += 1;
90 if let Some(tree) = entry.value.as_ref().map(|it| &it.tree) { 90 if let Some(tree) = entry.value.as_ref().map(|it| it.tree()) {
91 res.retained += 1; 91 res.retained += 1;
92 res.retained_size += tree.syntax().memory_size_of_subtree(); 92 res.retained_size += tree.syntax().memory_size_of_subtree();
93 } 93 }
diff --git a/crates/ra_ide_api/src/symbol_index.rs b/crates/ra_ide_api/src/symbol_index.rs
index f4a0c6ac7..1f2ba954e 100644
--- a/crates/ra_ide_api/src/symbol_index.rs
+++ b/crates/ra_ide_api/src/symbol_index.rs
@@ -34,9 +34,9 @@ use ra_db::{
34use ra_syntax::{ 34use ra_syntax::{
35 algo::visit::{visitor, Visitor}, 35 algo::visit::{visitor, Visitor},
36 ast::{self, NameOwner}, 36 ast::{self, NameOwner},
37 AstNode, SmolStr, SourceFile, 37 AstNode, Parse, SmolStr, SourceFile,
38 SyntaxKind::{self, *}, 38 SyntaxKind::{self, *},
39 SyntaxNode, SyntaxNodePtr, TextRange, TreeArc, WalkEvent, 39 SyntaxNode, SyntaxNodePtr, TextRange, WalkEvent,
40}; 40};
41use rayon::prelude::*; 41use rayon::prelude::*;
42 42
@@ -59,9 +59,9 @@ pub(crate) trait SymbolsDatabase: hir::db::HirDatabase {
59 59
60fn file_symbols(db: &impl SymbolsDatabase, file_id: FileId) -> Arc<SymbolIndex> { 60fn file_symbols(db: &impl SymbolsDatabase, file_id: FileId) -> Arc<SymbolIndex> {
61 db.check_canceled(); 61 db.check_canceled();
62 let source_file = db.parse(file_id).tree; 62 let parse = db.parse(file_id);
63 63
64 let symbols = source_file_to_file_symbols(&source_file, file_id); 64 let symbols = source_file_to_file_symbols(parse.tree(), file_id);
65 65
66 // FIXME: add macros here 66 // FIXME: add macros here
67 67
@@ -169,11 +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( 172 pub(crate) fn for_files(files: impl ParallelIterator<Item = (FileId, Parse)>) -> SymbolIndex {
173 files: impl ParallelIterator<Item = (FileId, TreeArc<SourceFile>)>,
174 ) -> SymbolIndex {
175 let symbols = files 173 let symbols = files
176 .flat_map(|(file_id, file)| source_file_to_file_symbols(&file, file_id)) 174 .flat_map(|(file_id, file)| source_file_to_file_symbols(file.tree(), file_id))
177 .collect::<Vec<_>>(); 175 .collect::<Vec<_>>();
178 SymbolIndex::new(symbols) 176 SymbolIndex::new(symbols)
179 } 177 }
diff --git a/crates/ra_ide_api/src/syntax_highlighting.rs b/crates/ra_ide_api/src/syntax_highlighting.rs
index 7c4285b02..d70ceb7d1 100644
--- a/crates/ra_ide_api/src/syntax_highlighting.rs
+++ b/crates/ra_ide_api/src/syntax_highlighting.rs
@@ -32,7 +32,8 @@ fn is_control_keyword(kind: SyntaxKind) -> bool {
32 32
33pub(crate) fn highlight(db: &RootDatabase, file_id: FileId) -> Vec<HighlightedRange> { 33pub(crate) fn highlight(db: &RootDatabase, file_id: FileId) -> Vec<HighlightedRange> {
34 let _p = profile("highlight"); 34 let _p = profile("highlight");
35 let source_file = db.parse(file_id).tree; 35 let parse = db.parse(file_id);
36 let root = parse.tree().syntax();
36 37
37 fn calc_binding_hash(file_id: FileId, text: &SmolStr, shadow_count: u32) -> u64 { 38 fn calc_binding_hash(file_id: FileId, text: &SmolStr, shadow_count: u32) -> u64 {
38 fn hash<T: std::hash::Hash + std::fmt::Debug>(x: T) -> u64 { 39 fn hash<T: std::hash::Hash + std::fmt::Debug>(x: T) -> u64 {
@@ -51,7 +52,7 @@ pub(crate) fn highlight(db: &RootDatabase, file_id: FileId) -> Vec<HighlightedRa
51 let mut bindings_shadow_count: FxHashMap<SmolStr, u32> = FxHashMap::default(); 52 let mut bindings_shadow_count: FxHashMap<SmolStr, u32> = FxHashMap::default();
52 53
53 let mut res = Vec::new(); 54 let mut res = Vec::new();
54 for node in source_file.syntax().descendants_with_tokens() { 55 for node in root.descendants_with_tokens() {
55 if highlighted.contains(&node) { 56 if highlighted.contains(&node) {
56 continue; 57 continue;
57 } 58 }
@@ -89,11 +90,8 @@ pub(crate) fn highlight(db: &RootDatabase, file_id: FileId) -> Vec<HighlightedRa
89 Some(SelfType(_)) => "type", 90 Some(SelfType(_)) => "type",
90 Some(Pat(ptr)) => { 91 Some(Pat(ptr)) => {
91 binding_hash = Some({ 92 binding_hash = Some({
92 let text = ptr 93 let text =
93 .syntax_node_ptr() 94 ptr.syntax_node_ptr().to_node(root).text().to_smol_string();
94 .to_node(&source_file.syntax())
95 .text()
96 .to_smol_string();
97 let shadow_count = 95 let shadow_count =
98 bindings_shadow_count.entry(text.clone()).or_default(); 96 bindings_shadow_count.entry(text.clone()).or_default();
99 calc_binding_hash(file_id, &text, *shadow_count) 97 calc_binding_hash(file_id, &text, *shadow_count)
@@ -178,7 +176,7 @@ pub(crate) fn highlight(db: &RootDatabase, file_id: FileId) -> Vec<HighlightedRa
178} 176}
179 177
180pub(crate) fn highlight_as_html(db: &RootDatabase, file_id: FileId, rainbow: bool) -> String { 178pub(crate) fn highlight_as_html(db: &RootDatabase, file_id: FileId, rainbow: bool) -> String {
181 let source_file = db.parse(file_id).tree; 179 let parse = db.parse(file_id);
182 180
183 fn rainbowify(seed: u64) -> String { 181 fn rainbowify(seed: u64) -> String {
184 use rand::prelude::*; 182 use rand::prelude::*;
@@ -200,7 +198,7 @@ pub(crate) fn highlight_as_html(db: &RootDatabase, file_id: FileId, rainbow: boo
200 let mut buf = String::new(); 198 let mut buf = String::new();
201 buf.push_str(&STYLE); 199 buf.push_str(&STYLE);
202 buf.push_str("<pre><code>"); 200 buf.push_str("<pre><code>");
203 let tokens = source_file.syntax().descendants_with_tokens().filter_map(|it| it.as_token()); 201 let tokens = parse.tree().syntax().descendants_with_tokens().filter_map(|it| it.as_token());
204 for token in tokens { 202 for token in tokens {
205 could_intersect.retain(|it| token.range().start() <= it.range.end()); 203 could_intersect.retain(|it| token.range().start() <= it.range.end());
206 while let Some(r) = ranges.get(frontier) { 204 while let Some(r) = ranges.get(frontier) {
diff --git a/crates/ra_ide_api/src/syntax_tree.rs b/crates/ra_ide_api/src/syntax_tree.rs
index 8bdd08d58..b3e08c041 100644
--- a/crates/ra_ide_api/src/syntax_tree.rs
+++ b/crates/ra_ide_api/src/syntax_tree.rs
@@ -13,9 +13,9 @@ pub(crate) fn syntax_tree(
13 file_id: FileId, 13 file_id: FileId,
14 text_range: Option<TextRange>, 14 text_range: Option<TextRange>,
15) -> String { 15) -> String {
16 let parse = db.parse(file_id);
16 if let Some(text_range) = text_range { 17 if let Some(text_range) = text_range {
17 let file = db.parse(file_id).tree; 18 let node = match algo::find_covering_element(parse.tree().syntax(), text_range) {
18 let node = match algo::find_covering_element(file.syntax(), text_range) {
19 SyntaxElement::Node(node) => node, 19 SyntaxElement::Node(node) => node,
20 SyntaxElement::Token(token) => { 20 SyntaxElement::Token(token) => {
21 if let Some(tree) = syntax_tree_for_string(token, text_range) { 21 if let Some(tree) = syntax_tree_for_string(token, text_range) {
@@ -27,7 +27,7 @@ pub(crate) fn syntax_tree(
27 27
28 node.debug_dump() 28 node.debug_dump()
29 } else { 29 } else {
30 db.parse(file_id).tree.syntax().debug_dump() 30 parse.tree().syntax().debug_dump()
31 } 31 }
32} 32}
33 33
@@ -84,8 +84,8 @@ fn syntax_tree_for_token(node: SyntaxToken, text_range: TextRange) -> Option<Str
84 84
85 // If the "file" parsed without errors, 85 // If the "file" parsed without errors,
86 // return its syntax 86 // return its syntax
87 if parsed.errors.is_empty() { 87 if parsed.errors().is_empty() {
88 return Some(parsed.tree.syntax().debug_dump()); 88 return Some(parsed.tree().syntax().debug_dump());
89 } 89 }
90 90
91 None 91 None
diff --git a/crates/ra_ide_api/src/typing.rs b/crates/ra_ide_api/src/typing.rs
index d3cb71ddb..01eb32b2f 100644
--- a/crates/ra_ide_api/src/typing.rs
+++ b/crates/ra_ide_api/src/typing.rs
@@ -11,7 +11,8 @@ use ra_syntax::{
11use ra_text_edit::{TextEdit, TextEditBuilder}; 11use ra_text_edit::{TextEdit, TextEditBuilder};
12 12
13pub(crate) fn on_enter(db: &RootDatabase, position: FilePosition) -> Option<SourceChange> { 13pub(crate) fn on_enter(db: &RootDatabase, position: FilePosition) -> Option<SourceChange> {
14 let file = db.parse(position.file_id).tree; 14 let parse = db.parse(position.file_id);
15 let file = parse.tree();
15 let comment = find_token_at_offset(file.syntax(), position.offset) 16 let comment = find_token_at_offset(file.syntax(), position.offset)
16 .left_biased() 17 .left_biased()
17 .and_then(ast::Comment::cast)?; 18 .and_then(ast::Comment::cast)?;
@@ -86,10 +87,10 @@ pub fn on_eq_typed(file: &SourceFile, eq_offset: TextUnit) -> Option<TextEdit> {
86} 87}
87 88
88pub(crate) fn on_dot_typed(db: &RootDatabase, position: FilePosition) -> Option<SourceChange> { 89pub(crate) fn on_dot_typed(db: &RootDatabase, position: FilePosition) -> Option<SourceChange> {
89 let file = db.parse(position.file_id).tree; 90 let parse = db.parse(position.file_id);
90 assert_eq!(file.syntax().text().char_at(position.offset), Some('.')); 91 assert_eq!(parse.tree().syntax().text().char_at(position.offset), Some('.'));
91 92
92 let whitespace = find_token_at_offset(file.syntax(), position.offset) 93 let whitespace = find_token_at_offset(parse.tree().syntax(), position.offset)
93 .left_biased() 94 .left_biased()
94 .and_then(ast::Whitespace::cast)?; 95 .and_then(ast::Whitespace::cast)?;
95 96
@@ -139,8 +140,8 @@ mod tests {
139 let mut edit = TextEditBuilder::default(); 140 let mut edit = TextEditBuilder::default();
140 edit.insert(offset, "=".to_string()); 141 edit.insert(offset, "=".to_string());
141 let before = edit.finish().apply(&before); 142 let before = edit.finish().apply(&before);
142 let file = SourceFile::parse(&before).tree; 143 let parse = SourceFile::parse(&before);
143 if let Some(result) = on_eq_typed(&file, offset) { 144 if let Some(result) = on_eq_typed(parse.tree(), offset) {
144 let actual = result.apply(&before); 145 let actual = result.apply(&before);
145 assert_eq_text!(after, &actual); 146 assert_eq_text!(after, &actual);
146 } else { 147 } else {
diff --git a/crates/ra_mbe/src/tests.rs b/crates/ra_mbe/src/tests.rs
index 1db35cd8d..5a1494fee 100644
--- a/crates/ra_mbe/src/tests.rs
+++ b/crates/ra_mbe/src/tests.rs
@@ -95,8 +95,8 @@ pub(crate) fn expand_to_expr(
95pub(crate) fn text_to_tokentree(text: &str) -> tt::Subtree { 95pub(crate) fn text_to_tokentree(text: &str) -> tt::Subtree {
96 // wrap the given text to a macro call 96 // wrap the given text to a macro call
97 let wrapped = format!("wrap_macro!( {} )", text); 97 let wrapped = format!("wrap_macro!( {} )", text);
98 let wrapped = ast::SourceFile::parse(&wrapped).tree; 98 let wrapped = ast::SourceFile::parse(&wrapped);
99 let wrapped = wrapped.syntax().descendants().find_map(ast::TokenTree::cast).unwrap(); 99 let wrapped = wrapped.tree().syntax().descendants().find_map(ast::TokenTree::cast).unwrap();
100 let mut wrapped = ast_to_token_tree(wrapped).unwrap().0; 100 let mut wrapped = ast_to_token_tree(wrapped).unwrap().0;
101 wrapped.delimiter = tt::Delimiter::None; 101 wrapped.delimiter = tt::Delimiter::None;
102 102
diff --git a/crates/ra_syntax/src/lib.rs b/crates/ra_syntax/src/lib.rs
index 9790a984d..06d3ea727 100644
--- a/crates/ra_syntax/src/lib.rs
+++ b/crates/ra_syntax/src/lib.rs
@@ -59,11 +59,19 @@ pub use rowan::{SmolStr, TextRange, TextUnit};
59/// files. 59/// files.
60#[derive(Debug, Clone, PartialEq, Eq)] 60#[derive(Debug, Clone, PartialEq, Eq)]
61pub struct Parse { 61pub struct Parse {
62 pub tree: TreeArc<SourceFile>, 62 tree: TreeArc<SourceFile>,
63 pub errors: Arc<Vec<SyntaxError>>, 63 errors: Arc<Vec<SyntaxError>>,
64} 64}
65 65
66impl Parse { 66impl Parse {
67 pub fn tree(&self) -> &SourceFile {
68 &*self.tree
69 }
70
71 pub fn errors(&self) -> &[SyntaxError] {
72 &*self.errors
73 }
74
67 pub fn ok(self) -> Result<TreeArc<SourceFile>, Arc<Vec<SyntaxError>>> { 75 pub fn ok(self) -> Result<TreeArc<SourceFile>, Arc<Vec<SyntaxError>>> {
68 if self.errors.is_empty() { 76 if self.errors.is_empty() {
69 Ok(self.tree) 77 Ok(self.tree)
diff --git a/crates/ra_syntax/tests/test.rs b/crates/ra_syntax/tests/test.rs
index 2442c8505..cabd3e9bd 100644
--- a/crates/ra_syntax/tests/test.rs
+++ b/crates/ra_syntax/tests/test.rs
@@ -22,7 +22,7 @@ fn lexer_tests() {
22fn parser_tests() { 22fn parser_tests() {
23 dir_tests(&test_data_dir(), &["parser/inline/ok", "parser/ok"], |text, path| { 23 dir_tests(&test_data_dir(), &["parser/inline/ok", "parser/ok"], |text, path| {
24 let parse = SourceFile::parse(text); 24 let parse = SourceFile::parse(text);
25 let errors = parse.errors.as_slice(); 25 let errors = parse.errors();
26 assert_eq!( 26 assert_eq!(
27 errors, 27 errors,
28 &[] as &[ra_syntax::SyntaxError], 28 &[] as &[ra_syntax::SyntaxError],
@@ -33,7 +33,7 @@ fn parser_tests() {
33 }); 33 });
34 dir_tests(&test_data_dir(), &["parser/err", "parser/inline/err"], |text, path| { 34 dir_tests(&test_data_dir(), &["parser/err", "parser/inline/err"], |text, path| {
35 let parse = SourceFile::parse(text); 35 let parse = SourceFile::parse(text);
36 let errors = parse.errors.as_slice(); 36 let errors = parse.errors();
37 assert!(!errors.is_empty(), "There should be errors in the file {:?}", path.display()); 37 assert!(!errors.is_empty(), "There should be errors in the file {:?}", path.display());
38 parse.debug_dump() 38 parse.debug_dump()
39 }); 39 });