From a6224f36200c768d49b6450204fd95edaa559b50 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 18 Jul 2019 22:29:20 +0300 Subject: make Parse generic --- crates/ra_db/src/lib.rs | 6 +-- .../src/completion/completion_context.rs | 4 +- crates/ra_ide_api/src/status.rs | 6 +-- crates/ra_ide_api/src/symbol_index.rs | 4 +- crates/ra_syntax/src/lib.rs | 47 +++++++++++++++------- 5 files changed, 44 insertions(+), 23 deletions(-) (limited to 'crates') 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; use std::{panic, sync::Arc}; use ra_prof::profile; -use ra_syntax::{Parse, SourceFile, TextRange, TextUnit}; +use ra_syntax::{ast, Parse, SourceFile, TextRange, TextUnit}; use relative_path::RelativePathBuf; pub use crate::{ @@ -74,7 +74,7 @@ pub trait SourceDatabase: CheckCanceled + std::fmt::Debug { fn file_text(&self, file_id: FileId) -> Arc; // Parses the file into the syntax tree. #[salsa::invoke(parse_query)] - fn parse(&self, file_id: FileId) -> Parse; + fn parse(&self, file_id: FileId) -> Parse; /// Path to a file, relative to the root of its source root. #[salsa::input] fn file_relative_path(&self, file_id: FileId) -> RelativePathBuf; @@ -98,7 +98,7 @@ fn source_root_crates(db: &impl SourceDatabase, id: SourceRootId) -> Arc Parse { +fn parse_query(db: &impl SourceDatabase, file_id: FileId) -> Parse { let _p = profile("parse_query"); let text = db.file_text(file_id); 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> { impl<'a> CompletionContext<'a> { pub(super) fn new( db: &'a db::RootDatabase, - original_parse: &'a Parse, + original_parse: &'a Parse, position: FilePosition, ) -> Option> { let module = source_binder::module_from_position(db, position); @@ -83,7 +83,7 @@ impl<'a> CompletionContext<'a> { } } - fn fill(&mut self, original_parse: &'a Parse, offset: TextUnit) { + fn fill(&mut self, original_parse: &'a Parse, offset: TextUnit) { // Insert a fake ident to get a valid parse tree. We will use this file // to determine context, though the original_file will be used for // 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::{ FileTextQuery, SourceRootId, }; use ra_prof::{memory_usage, Bytes}; -use ra_syntax::{AstNode, Parse, SyntaxNode, TreeArc}; +use ra_syntax::{ast, AstNode, Parse, SyntaxNode, TreeArc}; use crate::{ db::RootDatabase, @@ -79,10 +79,10 @@ impl fmt::Display for SyntaxTreeStats { } } -impl FromIterator> for SyntaxTreeStats { +impl FromIterator>> for SyntaxTreeStats { fn from_iter(iter: T) -> SyntaxTreeStats where - T: IntoIterator>, + T: IntoIterator>>, { let mut res = SyntaxTreeStats::default(); 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 { self.map.as_fst().size() + self.symbols.len() * mem::size_of::() } - pub(crate) fn for_files(files: impl ParallelIterator) -> SymbolIndex { + pub(crate) fn for_files( + files: impl ParallelIterator)>, + ) -> SymbolIndex { let symbols = files .flat_map(|(file_id, file)| source_file_to_file_symbols(file.tree(), file_id)) .collect::>(); 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}; use ra_text_edit::AtomTextEdit; -use crate::syntax_node::GreenNode; +use crate::syntax_node::{GreenNode, SyntaxNodeWrapper}; pub use crate::{ ast::{AstNode, AstToken}, @@ -57,14 +57,24 @@ pub use rowan::{SmolStr, TextRange, TextUnit}; /// /// Note that we always produce a syntax tree, even for completely invalid /// files. -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct Parse { - tree: TreeArc, +#[derive(Debug, PartialEq, Eq)] +pub struct Parse { + tree: TreeArc, errors: Arc>, } -impl Parse { - pub fn tree(&self) -> &SourceFile { +impl Clone for Parse { + fn clone(&self) -> Parse { + Parse { tree: self.tree.clone(), errors: self.errors.clone() } + } +} + +impl Parse { + fn new(tree: TreeArc, errors: Vec) -> Parse { + Parse { tree, errors: Arc::new(errors) } + } + + pub fn tree(&self) -> &T { &*self.tree } @@ -72,18 +82,16 @@ impl Parse { &*self.errors } - pub fn ok(self) -> Result, Arc>> { + pub fn ok(self) -> Result, Arc>> { if self.errors.is_empty() { Ok(self.tree) } else { Err(self.errors) } } +} - pub fn reparse(&self, edit: &AtomTextEdit) -> Parse { - self.incremental_reparse(edit).unwrap_or_else(|| self.full_reparse(edit)) - } - +impl Parse { pub fn debug_dump(&self) -> String { let mut buf = self.tree.syntax().debug_dump(); for err in self.errors.iter() { @@ -92,7 +100,11 @@ impl Parse { buf } - fn incremental_reparse(&self, edit: &AtomTextEdit) -> Option { + pub fn reparse(&self, edit: &AtomTextEdit) -> Parse { + self.incremental_reparse(edit).unwrap_or_else(|| self.full_reparse(edit)) + } + + fn incremental_reparse(&self, edit: &AtomTextEdit) -> Option> { // FIXME: validation errors are not handled here parsing::incremental_reparse(self.tree.syntax(), edit, self.errors.to_vec()).map( |(green_node, errors, _reparsed_range)| Parse { @@ -102,12 +114,19 @@ impl Parse { ) } - fn full_reparse(&self, edit: &AtomTextEdit) -> Parse { + fn full_reparse(&self, edit: &AtomTextEdit) -> Parse { let text = edit.apply(self.tree.syntax().text().to_string()); SourceFile::parse(&text) } } +impl Parse { + pub fn cast(self) -> Option> { + let node = T::cast(&self.tree)?; + Some(Parse { tree: node.to_owned(), errors: self.errors }) + } +} + /// `SourceFile` represents a parse tree for a single Rust file. pub use crate::ast::SourceFile; @@ -121,7 +140,7 @@ impl SourceFile { TreeArc::cast(root) } - pub fn parse(text: &str) -> Parse { + pub fn parse(text: &str) -> Parse { let (green, mut errors) = parsing::parse_text(text); let tree = SourceFile::new(green); errors.extend(validation::validate(&tree)); -- cgit v1.2.3