From deab4caa7b1ba81c1b7e6561bc270bbde6467f13 Mon Sep 17 00:00:00 2001
From: Aleksey Kladov <aleksey.kladov@gmail.com>
Date: Fri, 12 Jul 2019 19:41:13 +0300
Subject: make Parse fields private

this is in preparation for the new rowan API
---
 crates/ra_ide_api/src/call_info.rs                   |  4 ++--
 crates/ra_ide_api/src/change.rs                      |  4 ++--
 .../ra_ide_api/src/completion/completion_context.rs  |  6 +++---
 crates/ra_ide_api/src/diagnostics.rs                 | 12 ++++++------
 crates/ra_ide_api/src/display/navigation_target.rs   | 12 ++++++------
 crates/ra_ide_api/src/extend_selection.rs            |  8 ++++----
 crates/ra_ide_api/src/folding_ranges.rs              |  4 ++--
 crates/ra_ide_api/src/goto_definition.rs             |  4 ++--
 crates/ra_ide_api/src/goto_type_definition.rs        |  4 ++--
 crates/ra_ide_api/src/hover.rs                       |  7 ++++---
 crates/ra_ide_api/src/impls.rs                       |  4 ++--
 crates/ra_ide_api/src/join_lines.rs                  |  4 ++--
 crates/ra_ide_api/src/lib.rs                         | 20 +++++++++++---------
 crates/ra_ide_api/src/matching_brace.rs              |  4 ++--
 crates/ra_ide_api/src/references.rs                  |  8 ++++----
 crates/ra_ide_api/src/runnables.rs                   |  4 ++--
 crates/ra_ide_api/src/status.rs                      |  2 +-
 crates/ra_ide_api/src/symbol_index.rs                | 14 ++++++--------
 crates/ra_ide_api/src/syntax_highlighting.rs         | 16 +++++++---------
 crates/ra_ide_api/src/syntax_tree.rs                 | 10 +++++-----
 crates/ra_ide_api/src/typing.rs                      | 13 +++++++------
 21 files changed, 82 insertions(+), 82 deletions(-)

(limited to 'crates/ra_ide_api/src')

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};
 
 /// Computes parameter information for the given call expression.
 pub(crate) fn call_info(db: &RootDatabase, position: FilePosition) -> Option<CallInfo> {
-    let file = db.parse(position.file_id).tree;
-    let syntax = file.syntax();
+    let parse = db.parse(position.file_id);
+    let syntax = parse.tree().syntax();
 
     // Find the calling expression and it's NameRef
     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 {
         files: Vec<(FileId, RelativePathBuf, Arc<String>)>,
     ) -> LibraryData {
         let symbol_index = SymbolIndex::for_files(files.par_iter().map(|(file_id, _, text)| {
-            let file = SourceFile::parse(text).tree;
-            (*file_id, file)
+            let parse = SourceFile::parse(text);
+            (*file_id, parse)
         }));
         let mut root_change = RootChange::default();
         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> {
     ) -> Option<CompletionContext<'a>> {
         let module = source_binder::module_from_position(db, position);
         let token =
-            find_token_at_offset(original_parse.tree.syntax(), position.offset).left_biased()?;
+            find_token_at_offset(original_parse.tree().syntax(), position.offset).left_biased()?;
         let analyzer =
             hir::SourceAnalyzer::new(db, position.file_id, token.parent(), Some(position.offset));
         let mut ctx = CompletionContext {
@@ -89,7 +89,7 @@ impl<'a> CompletionContext<'a> {
         // actual completion.
         let file = {
             let edit = AtomTextEdit::insert(offset, "intellijRulezz".to_string());
-            original_parse.reparse(&edit).tree
+            original_parse.reparse(&edit).tree().to_owned()
         };
 
         // First, let's try to complete a reference to some declaration.
@@ -100,7 +100,7 @@ impl<'a> CompletionContext<'a> {
                 self.is_param = true;
                 return;
             }
-            self.classify_name_ref(&original_parse.tree, name_ref);
+            self.classify_name_ref(original_parse.tree(), name_ref);
         }
 
         // 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>
     let parse = db.parse(file_id);
     let mut res = Vec::new();
 
-    res.extend(parse.errors.iter().map(|err| Diagnostic {
+    res.extend(parse.errors().iter().map(|err| Diagnostic {
         range: location_to_range(err.location()),
         message: format!("Syntax Error: {}", err),
         severity: Severity::Error,
         fix: None,
     }));
 
-    for node in parse.tree.syntax().descendants() {
+    for node in parse.tree().syntax().descendants() {
         check_unnecessary_braces_in_use_statement(&mut res, file_id, node);
         check_struct_shorthand_initialization(&mut res, file_id, node);
     }
@@ -181,18 +181,18 @@ mod tests {
     type DiagnosticChecker = fn(&mut Vec<Diagnostic>, FileId, &SyntaxNode) -> Option<()>;
 
     fn check_not_applicable(code: &str, func: DiagnosticChecker) {
-        let file = SourceFile::parse(code).tree;
+        let parse = SourceFile::parse(code);
         let mut diagnostics = Vec::new();
-        for node in file.syntax().descendants() {
+        for node in parse.tree().syntax().descendants() {
             func(&mut diagnostics, FileId(0), node);
         }
         assert!(diagnostics.is_empty());
     }
 
     fn check_apply(before: &str, after: &str, func: DiagnosticChecker) {
-        let file = SourceFile::parse(before).tree;
+        let parse = SourceFile::parse(before);
         let mut diagnostics = Vec::new();
-        for node in file.syntax().descendants() {
+        for node in parse.tree().syntax().descendants() {
             func(&mut diagnostics, FileId(0), node);
         }
         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 {
         file_id: FileId,
         pat: AstPtr<ast::Pat>,
     ) -> NavigationTarget {
-        let file = db.parse(file_id).tree;
-        let (name, full_range) = match pat.to_node(file.syntax()).kind() {
+        let parse = db.parse(file_id);
+        let (name, full_range) = match pat.to_node(parse.tree().syntax()).kind() {
             ast::PatKind::BindPat(pat) => return NavigationTarget::from_bind_pat(file_id, &pat),
             _ => ("_".into(), pat.syntax_node_ptr().range()),
         };
@@ -315,8 +315,8 @@ impl NavigationTarget {
 }
 
 pub(crate) fn docs_from_symbol(db: &RootDatabase, symbol: &FileSymbol) -> Option<String> {
-    let file = db.parse(symbol.file_id).tree;
-    let node = symbol.ptr.to_node(file.syntax()).to_owned();
+    let parse = db.parse(symbol.file_id);
+    let node = symbol.ptr.to_node(parse.tree().syntax()).to_owned();
 
     fn doc_comments<N: ast::DocCommentsOwner>(node: &N) -> Option<String> {
         node.doc_comment_text()
@@ -341,8 +341,8 @@ pub(crate) fn docs_from_symbol(db: &RootDatabase, symbol: &FileSymbol) -> Option
 ///
 /// e.g. `struct Name`, `enum Name`, `fn Name`
 pub(crate) fn description_from_symbol(db: &RootDatabase, symbol: &FileSymbol) -> Option<String> {
-    let file = db.parse(symbol.file_id).tree;
-    let node = symbol.ptr.to_node(file.syntax()).to_owned();
+    let parse = db.parse(symbol.file_id);
+    let node = symbol.ptr.to_node(parse.tree().syntax()).to_owned();
 
     visitor()
         .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};
 
 // FIXME: restore macro support
 pub(crate) fn extend_selection(db: &RootDatabase, frange: FileRange) -> TextRange {
-    let source_file = db.parse(frange.file_id).tree;
-    try_extend_selection(source_file.syntax(), frange.range).unwrap_or(frange.range)
+    let parse = db.parse(frange.file_id);
+    try_extend_selection(parse.tree().syntax(), frange.range).unwrap_or(frange.range)
 }
 
 fn try_extend_selection(root: &SyntaxNode, range: TextRange) -> Option<TextRange> {
@@ -212,10 +212,10 @@ mod tests {
 
     fn do_check(before: &str, afters: &[&str]) {
         let (cursor, before) = extract_offset(before);
-        let file = SourceFile::parse(&before).tree;
+        let parse = SourceFile::parse(&before);
         let mut range = TextRange::offset_len(cursor, 0.into());
         for &after in afters {
-            range = try_extend_selection(file.syntax(), range).unwrap();
+            range = try_extend_selection(parse.tree().syntax(), range).unwrap();
             let actual = &before[range];
             assert_eq!(after, actual);
         }
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 {
 
     fn do_check(text: &str, fold_kinds: &[FoldKind]) {
         let (ranges, text) = extract_ranges(text, "fold");
-        let file = SourceFile::parse(&text).tree;
-        let folds = folding_ranges(&file);
+        let parse = SourceFile::parse(&text);
+        let folds = folding_ranges(parse.tree());
 
         assert_eq!(
             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(
     db: &RootDatabase,
     position: FilePosition,
 ) -> Option<RangeInfo<Vec<NavigationTarget>>> {
-    let file = db.parse(position.file_id).tree;
-    let syntax = file.syntax();
+    let parse = db.parse(position.file_id);
+    let syntax = parse.tree().syntax();
     if let Some(name_ref) = find_node_at_offset::<ast::NameRef>(syntax, position.offset) {
         let navs = reference_definition(db, position.file_id, name_ref).to_vec();
         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(
     db: &RootDatabase,
     position: FilePosition,
 ) -> Option<RangeInfo<Vec<NavigationTarget>>> {
-    let file = db.parse(position.file_id).tree;
+    let parse = db.parse(position.file_id);
 
-    let node = find_token_at_offset(file.syntax(), position.offset).find_map(|token| {
+    let node = find_token_at_offset(parse.tree().syntax(), position.offset).find_map(|token| {
         token
             .parent()
             .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> {
 }
 
 pub(crate) fn hover(db: &RootDatabase, position: FilePosition) -> Option<RangeInfo<HoverResult>> {
-    let file = db.parse(position.file_id).tree;
+    let parse = db.parse(position.file_id);
+    let file = parse.tree();
     let mut res = HoverResult::new();
 
     let mut range = None;
@@ -241,8 +242,8 @@ pub(crate) fn hover(db: &RootDatabase, position: FilePosition) -> Option<RangeIn
 }
 
 pub(crate) fn type_of(db: &RootDatabase, frange: FileRange) -> Option<String> {
-    let file = db.parse(frange.file_id).tree;
-    let syntax = file.syntax();
+    let parse = db.parse(frange.file_id);
+    let syntax = parse.tree().syntax();
     let leaf_node = find_covering_element(syntax, frange.range);
     // if we picked identifier, expand to pattern/expression
     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(
     db: &RootDatabase,
     position: FilePosition,
 ) -> Option<RangeInfo<Vec<NavigationTarget>>> {
-    let file = db.parse(position.file_id).tree;
-    let syntax = file.syntax();
+    let parse = db.parse(position.file_id);
+    let syntax = parse.tree().syntax();
 
     let module = source_binder::module_from_position(db, position)?;
 
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() {
 
     fn check_join_lines_sel(before: &str, after: &str) {
         let (sel, before) = extract_range(before);
-        let file = SourceFile::parse(&before).tree;
-        let result = join_lines(&file, sel);
+        let parse = SourceFile::parse(&before);
+        let result = join_lines(parse.tree(), sel);
         let actual = result.apply(&before);
         assert_eq_text!(after, &actual);
     }
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 {
 
     /// Gets the syntax tree of the file.
     pub fn parse(&self, file_id: FileId) -> TreeArc<SourceFile> {
-        self.db.parse(file_id).tree
+        self.db.parse(file_id).tree().to_owned()
     }
 
     /// Gets the file's `LineIndex`: data structure to convert between absolute
@@ -343,7 +343,8 @@ impl Analysis {
     /// Returns position of the matching brace (all types of braces are
     /// supported).
     pub fn matching_brace(&self, position: FilePosition) -> Option<TextUnit> {
-        let file = self.db.parse(position.file_id).tree;
+        let parse = self.db.parse(position.file_id);
+        let file = parse.tree();
         matching_brace::matching_brace(&file, position.offset)
     }
 
@@ -356,10 +357,10 @@ impl Analysis {
     /// Returns an edit to remove all newlines in the range, cleaning up minor
     /// stuff like trailing commas.
     pub fn join_lines(&self, frange: FileRange) -> SourceChange {
-        let file = self.db.parse(frange.file_id).tree;
+        let parse = self.db.parse(frange.file_id);
         let file_edit = SourceFileEdit {
             file_id: frange.file_id,
-            edit: join_lines::join_lines(&file, frange.range),
+            edit: join_lines::join_lines(parse.tree(), frange.range),
         };
         SourceChange::source_file_edit("join lines", file_edit)
     }
@@ -374,7 +375,8 @@ impl Analysis {
     /// this works when adding `let =`.
     // FIXME: use a snippet completion instead of this hack here.
     pub fn on_eq_typed(&self, position: FilePosition) -> Option<SourceChange> {
-        let file = self.db.parse(position.file_id).tree;
+        let parse = self.db.parse(position.file_id);
+        let file = parse.tree();
         let edit = typing::on_eq_typed(&file, position.offset)?;
         Some(SourceChange::source_file_edit(
             "add semicolon",
@@ -390,14 +392,14 @@ impl Analysis {
     /// Returns a tree representation of symbols in the file. Useful to draw a
     /// file outline.
     pub fn file_structure(&self, file_id: FileId) -> Vec<StructureNode> {
-        let file = self.db.parse(file_id).tree;
-        file_structure(&file)
+        let parse = self.db.parse(file_id);
+        file_structure(parse.tree())
     }
 
     /// Returns the set of folding ranges.
     pub fn folding_ranges(&self, file_id: FileId) -> Vec<Fold> {
-        let file = self.db.parse(file_id).tree;
-        folding_ranges::folding_ranges(&file)
+        let parse = self.db.parse(file_id);
+        folding_ranges::folding_ranges(parse.tree())
     }
 
     /// 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 {
     fn test_matching_brace() {
         fn do_check(before: &str, after: &str) {
             let (pos, before) = extract_offset(before);
-            let file = SourceFile::parse(&before).tree;
-            let new_pos = match matching_brace(&file, pos) {
+            let parse = SourceFile::parse(&before);
+            let new_pos = match matching_brace(parse.tree(), pos) {
                 None => pos,
                 Some(pos) => pos,
             };
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(
     db: &RootDatabase,
     position: FilePosition,
 ) -> Option<ReferenceSearchResult> {
-    let file = db.parse(position.file_id).tree;
-    let (binding, analyzer) = find_binding(db, &file, position)?;
+    let parse = db.parse(position.file_id);
+    let (binding, analyzer) = find_binding(db, parse.tree(), position)?;
     let declaration = NavigationTarget::from_bind_pat(position.file_id, binding);
 
     let references = analyzer
@@ -88,8 +88,8 @@ pub(crate) fn rename(
     position: FilePosition,
     new_name: &str,
 ) -> Option<SourceChange> {
-    let source_file = db.parse(position.file_id).tree;
-    let syntax = source_file.syntax();
+    let parse = db.parse(position.file_id);
+    let syntax = parse.tree().syntax();
 
     if let Some((ast_name, ast_module)) = find_name_and_module_at_offset(syntax, position) {
         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 {
 }
 
 pub(crate) fn runnables(db: &RootDatabase, file_id: FileId) -> Vec<Runnable> {
-    let source_file = db.parse(file_id).tree;
-    source_file.syntax().descendants().filter_map(|i| runnable(db, file_id, i)).collect()
+    let parse = db.parse(file_id);
+    parse.tree().syntax().descendants().filter_map(|i| runnable(db, file_id, i)).collect()
 }
 
 fn 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 {
         let mut res = SyntaxTreeStats::default();
         for entry in iter {
             res.total += 1;
-            if let Some(tree) = entry.value.as_ref().map(|it| &it.tree) {
+            if let Some(tree) = entry.value.as_ref().map(|it| it.tree()) {
                 res.retained += 1;
                 res.retained_size += tree.syntax().memory_size_of_subtree();
             }
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::{
 use ra_syntax::{
     algo::visit::{visitor, Visitor},
     ast::{self, NameOwner},
-    AstNode, SmolStr, SourceFile,
+    AstNode, Parse, SmolStr, SourceFile,
     SyntaxKind::{self, *},
-    SyntaxNode, SyntaxNodePtr, TextRange, TreeArc, WalkEvent,
+    SyntaxNode, SyntaxNodePtr, TextRange, WalkEvent,
 };
 use rayon::prelude::*;
 
@@ -59,9 +59,9 @@ pub(crate) trait SymbolsDatabase: hir::db::HirDatabase {
 
 fn file_symbols(db: &impl SymbolsDatabase, file_id: FileId) -> Arc<SymbolIndex> {
     db.check_canceled();
-    let source_file = db.parse(file_id).tree;
+    let parse = db.parse(file_id);
 
-    let symbols = source_file_to_file_symbols(&source_file, file_id);
+    let symbols = source_file_to_file_symbols(parse.tree(), file_id);
 
     // FIXME: add macros here
 
@@ -169,11 +169,9 @@ impl SymbolIndex {
         self.map.as_fst().size() + self.symbols.len() * mem::size_of::<FileSymbol>()
     }
 
-    pub(crate) fn for_files(
-        files: impl ParallelIterator<Item = (FileId, TreeArc<SourceFile>)>,
-    ) -> SymbolIndex {
+    pub(crate) fn for_files(files: impl ParallelIterator<Item = (FileId, Parse)>) -> SymbolIndex {
         let symbols = files
-            .flat_map(|(file_id, file)| source_file_to_file_symbols(&file, file_id))
+            .flat_map(|(file_id, file)| source_file_to_file_symbols(file.tree(), file_id))
             .collect::<Vec<_>>();
         SymbolIndex::new(symbols)
     }
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 {
 
 pub(crate) fn highlight(db: &RootDatabase, file_id: FileId) -> Vec<HighlightedRange> {
     let _p = profile("highlight");
-    let source_file = db.parse(file_id).tree;
+    let parse = db.parse(file_id);
+    let root = parse.tree().syntax();
 
     fn calc_binding_hash(file_id: FileId, text: &SmolStr, shadow_count: u32) -> u64 {
         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
     let mut bindings_shadow_count: FxHashMap<SmolStr, u32> = FxHashMap::default();
 
     let mut res = Vec::new();
-    for node in source_file.syntax().descendants_with_tokens() {
+    for node in root.descendants_with_tokens() {
         if highlighted.contains(&node) {
             continue;
         }
@@ -89,11 +90,8 @@ pub(crate) fn highlight(db: &RootDatabase, file_id: FileId) -> Vec<HighlightedRa
                         Some(SelfType(_)) => "type",
                         Some(Pat(ptr)) => {
                             binding_hash = Some({
-                                let text = ptr
-                                    .syntax_node_ptr()
-                                    .to_node(&source_file.syntax())
-                                    .text()
-                                    .to_smol_string();
+                                let text =
+                                    ptr.syntax_node_ptr().to_node(root).text().to_smol_string();
                                 let shadow_count =
                                     bindings_shadow_count.entry(text.clone()).or_default();
                                 calc_binding_hash(file_id, &text, *shadow_count)
@@ -178,7 +176,7 @@ pub(crate) fn highlight(db: &RootDatabase, file_id: FileId) -> Vec<HighlightedRa
 }
 
 pub(crate) fn highlight_as_html(db: &RootDatabase, file_id: FileId, rainbow: bool) -> String {
-    let source_file = db.parse(file_id).tree;
+    let parse = db.parse(file_id);
 
     fn rainbowify(seed: u64) -> String {
         use rand::prelude::*;
@@ -200,7 +198,7 @@ pub(crate) fn highlight_as_html(db: &RootDatabase, file_id: FileId, rainbow: boo
     let mut buf = String::new();
     buf.push_str(&STYLE);
     buf.push_str("<pre><code>");
-    let tokens = source_file.syntax().descendants_with_tokens().filter_map(|it| it.as_token());
+    let tokens = parse.tree().syntax().descendants_with_tokens().filter_map(|it| it.as_token());
     for token in tokens {
         could_intersect.retain(|it| token.range().start() <= it.range.end());
         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(
     file_id: FileId,
     text_range: Option<TextRange>,
 ) -> String {
+    let parse = db.parse(file_id);
     if let Some(text_range) = text_range {
-        let file = db.parse(file_id).tree;
-        let node = match algo::find_covering_element(file.syntax(), text_range) {
+        let node = match algo::find_covering_element(parse.tree().syntax(), text_range) {
             SyntaxElement::Node(node) => node,
             SyntaxElement::Token(token) => {
                 if let Some(tree) = syntax_tree_for_string(token, text_range) {
@@ -27,7 +27,7 @@ pub(crate) fn syntax_tree(
 
         node.debug_dump()
     } else {
-        db.parse(file_id).tree.syntax().debug_dump()
+        parse.tree().syntax().debug_dump()
     }
 }
 
@@ -84,8 +84,8 @@ fn syntax_tree_for_token(node: SyntaxToken, text_range: TextRange) -> Option<Str
 
     // If the "file" parsed without errors,
     // return its syntax
-    if parsed.errors.is_empty() {
-        return Some(parsed.tree.syntax().debug_dump());
+    if parsed.errors().is_empty() {
+        return Some(parsed.tree().syntax().debug_dump());
     }
 
     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::{
 use ra_text_edit::{TextEdit, TextEditBuilder};
 
 pub(crate) fn on_enter(db: &RootDatabase, position: FilePosition) -> Option<SourceChange> {
-    let file = db.parse(position.file_id).tree;
+    let parse = db.parse(position.file_id);
+    let file = parse.tree();
     let comment = find_token_at_offset(file.syntax(), position.offset)
         .left_biased()
         .and_then(ast::Comment::cast)?;
@@ -86,10 +87,10 @@ pub fn on_eq_typed(file: &SourceFile, eq_offset: TextUnit) -> Option<TextEdit> {
 }
 
 pub(crate) fn on_dot_typed(db: &RootDatabase, position: FilePosition) -> Option<SourceChange> {
-    let file = db.parse(position.file_id).tree;
-    assert_eq!(file.syntax().text().char_at(position.offset), Some('.'));
+    let parse = db.parse(position.file_id);
+    assert_eq!(parse.tree().syntax().text().char_at(position.offset), Some('.'));
 
-    let whitespace = find_token_at_offset(file.syntax(), position.offset)
+    let whitespace = find_token_at_offset(parse.tree().syntax(), position.offset)
         .left_biased()
         .and_then(ast::Whitespace::cast)?;
 
@@ -139,8 +140,8 @@ mod tests {
             let mut edit = TextEditBuilder::default();
             edit.insert(offset, "=".to_string());
             let before = edit.finish().apply(&before);
-            let file = SourceFile::parse(&before).tree;
-            if let Some(result) = on_eq_typed(&file, offset) {
+            let parse = SourceFile::parse(&before);
+            if let Some(result) = on_eq_typed(parse.tree(), offset) {
                 let actual = result.apply(&before);
                 assert_eq_text!(after, &actual);
             } else {
-- 
cgit v1.2.3