From c2c64145cb0487b20b79d4bf470cda7e39fcb236 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 30 Aug 2018 13:12:49 +0300 Subject: [PATCH] move --- crates/libanalysis/Cargo.toml | 1 - crates/libanalysis/src/api.rs | 142 -------------------- crates/libanalysis/src/imp.rs | 46 +++---- crates/libanalysis/src/lib.rs | 174 ++++++++++++++++++++++++- crates/libanalysis/src/symbol_index.rs | 32 +---- crates/libanalysis/tests/tests.rs | 10 +- 6 files changed, 193 insertions(+), 212 deletions(-) delete mode 100644 crates/libanalysis/src/api.rs diff --git a/crates/libanalysis/Cargo.toml b/crates/libanalysis/Cargo.toml index 5aca84f0ec..1f072533cf 100644 --- a/crates/libanalysis/Cargo.toml +++ b/crates/libanalysis/Cargo.toml @@ -6,7 +6,6 @@ authors = ["Aleksey Kladov "] [dependencies] relative-path = "0.3.7" log = "0.4.2" -failure = "0.1.2" parking_lot = "0.6.3" once_cell = "0.1.4" rayon = "1.0.2" diff --git a/crates/libanalysis/src/api.rs b/crates/libanalysis/src/api.rs deleted file mode 100644 index ded88cd15f..0000000000 --- a/crates/libanalysis/src/api.rs +++ /dev/null @@ -1,142 +0,0 @@ -use relative_path::{RelativePath, RelativePathBuf}; -use libsyntax2::{File, TextRange, TextUnit, AtomEdit}; -use libeditor; -use {imp::{AnalysisImpl, AnalysisHostImpl}, Query}; - -pub use libeditor::{ - LocalEdit, StructureNode, LineIndex, FileSymbol, - Runnable, RunnableKind, HighlightedRange, CompletionItem -}; - -#[derive(Debug)] -pub struct SourceChange { - pub label: String, - pub source_file_edits: Vec, - pub file_system_edits: Vec, - pub cursor_position: Option, -} - -#[derive(Debug)] -pub struct Position { - pub file_id: FileId, - pub offset: TextUnit, -} - -#[derive(Debug)] -pub struct SourceFileEdit { - pub file_id: FileId, - pub edits: Vec, -} - -#[derive(Debug)] -pub enum FileSystemEdit { - CreateFile { - anchor: FileId, - path: RelativePathBuf, - }, - MoveFile { - file: FileId, - path: RelativePathBuf, - } -} - -#[derive(Debug)] -pub struct Diagnostic { - pub message: String, - pub range: TextRange, - pub fix: Option, -} - -#[derive(Clone, Debug)] -pub struct Analysis { - pub(crate) imp: AnalysisImpl -} - -impl Analysis { - pub fn file_syntax(&self, file_id: FileId) -> File { - self.imp.file_syntax(file_id) - } - pub fn file_line_index(&self, file_id: FileId) -> LineIndex { - self.imp.file_line_index(file_id) - } - pub fn extend_selection(&self, file: &File, range: TextRange) -> TextRange { - libeditor::extend_selection(file, range).unwrap_or(range) - } - pub fn matching_brace(&self, file: &File, offset: TextUnit) -> Option { - libeditor::matching_brace(file, offset) - } - pub fn syntax_tree(&self, file_id: FileId) -> String { - let file = self.file_syntax(file_id); - libeditor::syntax_tree(&file) - } - pub fn join_lines(&self, file_id: FileId, range: TextRange) -> SourceChange { - let file = self.file_syntax(file_id); - SourceChange::from_local_edit(file_id, "join lines", libeditor::join_lines(&file, range)) - } - pub fn on_eq_typed(&self, file_id: FileId, offset: TextUnit) -> Option { - let file = self.file_syntax(file_id); - Some(SourceChange::from_local_edit(file_id, "add semicolon", libeditor::on_eq_typed(&file, offset)?)) - } - pub fn file_structure(&self, file_id: FileId) -> Vec { - let file = self.file_syntax(file_id); - libeditor::file_structure(&file) - } - pub fn symbol_search(&self, query: Query) -> Vec<(FileId, FileSymbol)> { - self.imp.world_symbols(query) - } - pub fn approximately_resolve_symbol(&self, file_id: FileId, offset: TextUnit) -> Vec<(FileId, FileSymbol)> { - self.imp.approximately_resolve_symbol(file_id, offset) - } - pub fn parent_module(&self, file_id: FileId) -> Vec<(FileId, FileSymbol)> { - self.imp.parent_module(file_id) - } - pub fn runnables(&self, file_id: FileId) -> Vec { - let file = self.file_syntax(file_id); - libeditor::runnables(&file) - } - pub fn highlight(&self, file_id: FileId) -> Vec { - let file = self.file_syntax(file_id); - libeditor::highlight(&file) - } - pub fn completions(&self, file_id: FileId, offset: TextUnit) -> Option> { - let file = self.file_syntax(file_id); - libeditor::scope_completion(&file, offset) - } - pub fn assists(&self, file_id: FileId, offset: TextUnit) -> Vec { - self.imp.assists(file_id, offset) - } - pub fn diagnostics(&self, file_id: FileId) -> Vec { - self.imp.diagnostics(file_id) - } -} - -pub trait FileResolver: Send + Sync + 'static { - fn file_stem(&self, id: FileId) -> String; - fn resolve(&self, id: FileId, path: &RelativePath) -> Option; -} - -#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] -pub struct FileId(pub u32); - -#[derive(Debug)] -pub struct AnalysisHost { - pub(crate) imp: AnalysisHostImpl -} - -impl AnalysisHost { - pub fn new() -> AnalysisHost { - AnalysisHost { imp: AnalysisHostImpl::new() } - } - - pub fn analysis(&self, file_resolver: impl FileResolver) -> Analysis { - Analysis { imp: self.imp.analysis(file_resolver) } - } - - pub fn change_file(&mut self, file_id: FileId, text: Option) { - self.change_files(::std::iter::once((file_id, text))); - } - - pub fn change_files(&mut self, changes: impl Iterator)>) { - self.imp.change_files(changes) - } -} diff --git a/crates/libanalysis/src/imp.rs b/crates/libanalysis/src/imp.rs index 06bbc7cf25..004942e72b 100644 --- a/crates/libanalysis/src/imp.rs +++ b/crates/libanalysis/src/imp.rs @@ -9,14 +9,14 @@ use std::{ panic, }; +use rayon::prelude::*; +use once_cell::sync::OnceCell; +use libeditor::{self, FileSymbol, LineIndex, find_node_at_offset, LocalEdit}; use libsyntax2::{ TextUnit, TextRange, SmolStr, File, AstNode, SyntaxKind::*, ast::{self, NameOwner}, }; -use rayon::prelude::*; -use once_cell::sync::OnceCell; -use libeditor::{self, FileSymbol, LineIndex, find_node_at_offset, LocalEdit}; use { FileId, FileResolver, Query, Diagnostic, SourceChange, SourceFileEdit, Position, FileSystemEdit, @@ -44,11 +44,11 @@ impl AnalysisHostImpl { AnalysisImpl { needs_reindex: AtomicBool::new(false), file_resolver: Arc::new(file_resolver), - data: self.data.clone() + data: self.data.clone(), } } - pub fn change_files(&mut self, changes: impl Iterator)>) { + pub fn change_files(&mut self, changes: &mut dyn Iterator)>) { let data = self.data_mut(); for (file_id, text) in changes { let change_kind = if data.file_map.remove(&file_id).is_some() { @@ -72,20 +72,14 @@ impl AnalysisHostImpl { } fn data_mut(&mut self) -> &mut WorldData { - if Arc::get_mut(&mut self.data).is_none() { - self.data = Arc::new(WorldData { - file_map: self.data.file_map.clone(), - module_map: self.data.module_map.clone(), - }); - } - Arc::get_mut(&mut self.data).unwrap() + Arc::make_mut(&mut self.data) } } pub(crate) struct AnalysisImpl { - pub(crate) needs_reindex: AtomicBool, - pub(crate) file_resolver: Arc, - pub(crate) data: Arc, + needs_reindex: AtomicBool, + file_resolver: Arc, + data: Arc, } impl fmt::Debug for AnalysisImpl { @@ -280,7 +274,7 @@ impl AnalysisImpl { } fn reindex(&self) { - if self.needs_reindex.compare_and_swap(false, true, SeqCst) { + if self.needs_reindex.compare_and_swap(true, false, SeqCst) { let now = Instant::now(); let data = &*self.data; data.file_map @@ -298,22 +292,22 @@ impl AnalysisImpl { } } -#[derive(Default, Debug)] -pub(crate) struct WorldData { - pub(crate) file_map: HashMap>, - pub(crate) module_map: ModuleMap, +#[derive(Clone, Default, Debug)] +struct WorldData { + file_map: HashMap>, + module_map: ModuleMap, } #[derive(Debug)] -pub(crate) struct FileData { - pub(crate) text: String, - pub(crate) symbols: OnceCell, - pub(crate) syntax: OnceCell, - pub(crate) lines: OnceCell, +struct FileData { + text: String, + symbols: OnceCell, + syntax: OnceCell, + lines: OnceCell, } impl FileData { - pub(crate) fn new(text: String) -> FileData { + fn new(text: String) -> FileData { FileData { text, symbols: OnceCell::new(), diff --git a/crates/libanalysis/src/lib.rs b/crates/libanalysis/src/lib.rs index a39141941f..8102286329 100644 --- a/crates/libanalysis/src/lib.rs +++ b/crates/libanalysis/src/lib.rs @@ -1,4 +1,3 @@ -extern crate failure; extern crate parking_lot; #[macro_use] extern crate log; @@ -11,13 +10,174 @@ extern crate relative_path; mod symbol_index; mod module_map; -mod api; mod imp; -pub use self::symbol_index::Query; -pub use self::api::{ - AnalysisHost, Analysis, SourceChange, SourceFileEdit, FileSystemEdit, Position, Diagnostic, Runnable, RunnableKind, - FileId, FileResolver, +use relative_path::{RelativePath, RelativePathBuf}; +use libsyntax2::{File, TextRange, TextUnit, AtomEdit}; +use imp::{AnalysisImpl, AnalysisHostImpl}; + +pub use libeditor::{ + StructureNode, LineIndex, FileSymbol, + Runnable, RunnableKind, HighlightedRange, CompletionItem, }; -pub type Result = ::std::result::Result; +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub struct FileId(pub u32); + +pub trait FileResolver: Send + Sync + 'static { + fn file_stem(&self, id: FileId) -> String; + fn resolve(&self, id: FileId, path: &RelativePath) -> Option; +} + +#[derive(Debug)] +pub struct AnalysisHost { + pub(crate) imp: AnalysisHostImpl +} + +impl AnalysisHost { + pub fn new() -> AnalysisHost { + AnalysisHost { imp: AnalysisHostImpl::new() } + } + pub fn analysis(&self, file_resolver: impl FileResolver) -> Analysis { + Analysis { imp: self.imp.analysis(file_resolver) } + } + pub fn change_file(&mut self, file_id: FileId, text: Option) { + self.change_files(::std::iter::once((file_id, text))); + } + pub fn change_files(&mut self, mut changes: impl Iterator)>) { + self.imp.change_files(&mut changes) + } +} + +#[derive(Debug)] +pub struct SourceChange { + pub label: String, + pub source_file_edits: Vec, + pub file_system_edits: Vec, + pub cursor_position: Option, +} + +#[derive(Debug)] +pub struct Position { + pub file_id: FileId, + pub offset: TextUnit, +} + +#[derive(Debug)] +pub struct SourceFileEdit { + pub file_id: FileId, + pub edits: Vec, +} + +#[derive(Debug)] +pub enum FileSystemEdit { + CreateFile { + anchor: FileId, + path: RelativePathBuf, + }, + MoveFile { + file: FileId, + path: RelativePathBuf, + } +} + +#[derive(Debug)] +pub struct Diagnostic { + pub message: String, + pub range: TextRange, + pub fix: Option, +} + +#[derive(Debug)] +pub struct Query { + query: String, + lowercased: String, + only_types: bool, + exact: bool, + limit: usize, +} + +impl Query { + pub fn new(query: String) -> Query { + let lowercased = query.to_lowercase(); + Query { + query, + lowercased, + only_types: false, + exact: false, + limit: usize::max_value() + } + } + pub fn only_types(&mut self) { + self.only_types = true; + } + pub fn exact(&mut self) { + self.exact = true; + } + pub fn limit(&mut self, limit: usize) { + self.limit = limit + } +} + +#[derive(Clone, Debug)] +pub struct Analysis { + pub(crate) imp: AnalysisImpl +} + +impl Analysis { + pub fn file_syntax(&self, file_id: FileId) -> File { + self.imp.file_syntax(file_id) + } + pub fn file_line_index(&self, file_id: FileId) -> LineIndex { + self.imp.file_line_index(file_id) + } + pub fn extend_selection(&self, file: &File, range: TextRange) -> TextRange { + libeditor::extend_selection(file, range).unwrap_or(range) + } + pub fn matching_brace(&self, file: &File, offset: TextUnit) -> Option { + libeditor::matching_brace(file, offset) + } + pub fn syntax_tree(&self, file_id: FileId) -> String { + let file = self.file_syntax(file_id); + libeditor::syntax_tree(&file) + } + pub fn join_lines(&self, file_id: FileId, range: TextRange) -> SourceChange { + let file = self.file_syntax(file_id); + SourceChange::from_local_edit(file_id, "join lines", libeditor::join_lines(&file, range)) + } + pub fn on_eq_typed(&self, file_id: FileId, offset: TextUnit) -> Option { + let file = self.file_syntax(file_id); + Some(SourceChange::from_local_edit(file_id, "add semicolon", libeditor::on_eq_typed(&file, offset)?)) + } + pub fn file_structure(&self, file_id: FileId) -> Vec { + let file = self.file_syntax(file_id); + libeditor::file_structure(&file) + } + pub fn symbol_search(&self, query: Query) -> Vec<(FileId, FileSymbol)> { + self.imp.world_symbols(query) + } + pub fn approximately_resolve_symbol(&self, file_id: FileId, offset: TextUnit) -> Vec<(FileId, FileSymbol)> { + self.imp.approximately_resolve_symbol(file_id, offset) + } + pub fn parent_module(&self, file_id: FileId) -> Vec<(FileId, FileSymbol)> { + self.imp.parent_module(file_id) + } + pub fn runnables(&self, file_id: FileId) -> Vec { + let file = self.file_syntax(file_id); + libeditor::runnables(&file) + } + pub fn highlight(&self, file_id: FileId) -> Vec { + let file = self.file_syntax(file_id); + libeditor::highlight(&file) + } + pub fn completions(&self, file_id: FileId, offset: TextUnit) -> Option> { + let file = self.file_syntax(file_id); + libeditor::scope_completion(&file, offset) + } + pub fn assists(&self, file_id: FileId, offset: TextUnit) -> Vec { + self.imp.assists(file_id, offset) + } + pub fn diagnostics(&self, file_id: FileId) -> Vec { + self.imp.diagnostics(file_id) + } +} diff --git a/crates/libanalysis/src/symbol_index.rs b/crates/libanalysis/src/symbol_index.rs index 73cbf5702f..cb35ab1d18 100644 --- a/crates/libanalysis/src/symbol_index.rs +++ b/crates/libanalysis/src/symbol_index.rs @@ -4,6 +4,7 @@ use libsyntax2::{ SyntaxKind::{self, *}, }; use fst::{self, IntoStreamer, Streamer}; +use Query; #[derive(Debug)] pub(crate) struct FileSymbols { @@ -30,38 +31,7 @@ impl FileSymbols { } } -pub struct Query { - query: String, - lowercased: String, - only_types: bool, - exact: bool, - limit: usize, -} - impl Query { - pub fn new(query: String) -> Query { - let lowercased = query.to_lowercase(); - Query { - query, - lowercased, - only_types: false, - exact: false, - limit: usize::max_value() - } - } - - pub fn only_types(&mut self) { - self.only_types = true; - } - - pub fn exact(&mut self) { - self.exact = true; - } - - pub fn limit(&mut self, limit: usize) { - self.limit = limit - } - pub(crate) fn process( &mut self, file: &FileSymbols, diff --git a/crates/libanalysis/tests/tests.rs b/crates/libanalysis/tests/tests.rs index 5893efaf6a..2f1299463f 100644 --- a/crates/libanalysis/tests/tests.rs +++ b/crates/libanalysis/tests/tests.rs @@ -5,7 +5,7 @@ extern crate test_utils; use std::path::{Path}; use relative_path::RelativePath; -use libanalysis::{WorldState, FileId, FileResolver}; +use libanalysis::{AnalysisHost, FileId, FileResolver}; use test_utils::assert_eq_dbg; struct FileMap(&'static [(u32, &'static str)]); @@ -37,7 +37,7 @@ impl FileResolver for FileMap { #[test] fn test_resolve_module() { - let mut world = WorldState::new(); + let mut world = AnalysisHost::new(); world.change_file(FileId(1), Some("mod foo;".to_string())); world.change_file(FileId(2), Some("".to_string())); @@ -64,7 +64,7 @@ fn test_resolve_module() { #[test] fn test_unresolved_module_diagnostic() { - let mut world = WorldState::new(); + let mut world = AnalysisHost::new(); world.change_file(FileId(1), Some("mod foo;".to_string())); let snap = world.analysis(FileMap(&[(1, "/lib.rs")])); @@ -84,7 +84,7 @@ fn test_unresolved_module_diagnostic() { #[test] fn test_unresolved_module_diagnostic_no_diag_for_inline_mode() { - let mut world = WorldState::new(); + let mut world = AnalysisHost::new(); world.change_file(FileId(1), Some("mod foo {}".to_string())); let snap = world.analysis(FileMap(&[(1, "/lib.rs")])); @@ -97,7 +97,7 @@ fn test_unresolved_module_diagnostic_no_diag_for_inline_mode() { #[test] fn test_resolve_parent_module() { - let mut world = WorldState::new(); + let mut world = AnalysisHost::new(); world.change_file(FileId(1), Some("mod foo;".to_string())); world.change_file(FileId(2), Some("".to_string()));