mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-28 05:53:45 +00:00
Merge #3551
3551: Move FeatureFlags r=matklad a=matklad
bors r+
🤖
Co-authored-by: Aleksey Kladov <aleksey.kladov@gmail.com>
This commit is contained in:
commit
e5df8c4028
14 changed files with 88 additions and 68 deletions
|
@ -33,6 +33,23 @@ pub use crate::completion::completion_item::{
|
||||||
CompletionItem, CompletionItemKind, InsertTextFormat,
|
CompletionItem, CompletionItemKind, InsertTextFormat,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||||
|
pub struct CompletionOptions {
|
||||||
|
pub enable_postfix_completions: bool,
|
||||||
|
pub add_call_parenthesis: bool,
|
||||||
|
pub add_call_argument_snippets: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for CompletionOptions {
|
||||||
|
fn default() -> Self {
|
||||||
|
CompletionOptions {
|
||||||
|
enable_postfix_completions: true,
|
||||||
|
add_call_parenthesis: true,
|
||||||
|
add_call_argument_snippets: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Main entry point for completion. We run completion as a two-phase process.
|
/// Main entry point for completion. We run completion as a two-phase process.
|
||||||
///
|
///
|
||||||
/// First, we look at the position and collect a so-called `CompletionContext.
|
/// First, we look at the position and collect a so-called `CompletionContext.
|
||||||
|
@ -55,8 +72,12 @@ pub use crate::completion::completion_item::{
|
||||||
/// `foo` *should* be present among the completion variants. Filtering by
|
/// `foo` *should* be present among the completion variants. Filtering by
|
||||||
/// identifier prefix/fuzzy match should be done higher in the stack, together
|
/// identifier prefix/fuzzy match should be done higher in the stack, together
|
||||||
/// with ordering of completions (currently this is done by the client).
|
/// with ordering of completions (currently this is done by the client).
|
||||||
pub(crate) fn completions(db: &RootDatabase, position: FilePosition) -> Option<Completions> {
|
pub(crate) fn completions(
|
||||||
let ctx = CompletionContext::new(db, position)?;
|
db: &RootDatabase,
|
||||||
|
position: FilePosition,
|
||||||
|
opts: &CompletionOptions,
|
||||||
|
) -> Option<Completions> {
|
||||||
|
let ctx = CompletionContext::new(db, position, opts)?;
|
||||||
|
|
||||||
let mut acc = Completions::default();
|
let mut acc = Completions::default();
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ use crate::{
|
||||||
};
|
};
|
||||||
|
|
||||||
pub(super) fn complete_postfix(acc: &mut Completions, ctx: &CompletionContext) {
|
pub(super) fn complete_postfix(acc: &mut Completions, ctx: &CompletionContext) {
|
||||||
if !ctx.db.feature_flags.get("completion.enable-postfix") {
|
if !ctx.options.enable_postfix_completions {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ use ra_syntax::{
|
||||||
};
|
};
|
||||||
use ra_text_edit::AtomTextEdit;
|
use ra_text_edit::AtomTextEdit;
|
||||||
|
|
||||||
use crate::FilePosition;
|
use crate::{completion::CompletionOptions, FilePosition};
|
||||||
|
|
||||||
/// `CompletionContext` is created early during completion to figure out, where
|
/// `CompletionContext` is created early during completion to figure out, where
|
||||||
/// exactly is the cursor, syntax-wise.
|
/// exactly is the cursor, syntax-wise.
|
||||||
|
@ -19,6 +19,7 @@ use crate::FilePosition;
|
||||||
pub(crate) struct CompletionContext<'a> {
|
pub(crate) struct CompletionContext<'a> {
|
||||||
pub(super) sema: Semantics<'a, RootDatabase>,
|
pub(super) sema: Semantics<'a, RootDatabase>,
|
||||||
pub(super) db: &'a RootDatabase,
|
pub(super) db: &'a RootDatabase,
|
||||||
|
pub(super) options: &'a CompletionOptions,
|
||||||
pub(super) offset: TextUnit,
|
pub(super) offset: TextUnit,
|
||||||
/// The token before the cursor, in the original file.
|
/// The token before the cursor, in the original file.
|
||||||
pub(super) original_token: SyntaxToken,
|
pub(super) original_token: SyntaxToken,
|
||||||
|
@ -57,6 +58,7 @@ impl<'a> CompletionContext<'a> {
|
||||||
pub(super) fn new(
|
pub(super) fn new(
|
||||||
db: &'a RootDatabase,
|
db: &'a RootDatabase,
|
||||||
position: FilePosition,
|
position: FilePosition,
|
||||||
|
options: &'a CompletionOptions,
|
||||||
) -> Option<CompletionContext<'a>> {
|
) -> Option<CompletionContext<'a>> {
|
||||||
let sema = Semantics::new(db);
|
let sema = Semantics::new(db);
|
||||||
|
|
||||||
|
@ -80,6 +82,7 @@ impl<'a> CompletionContext<'a> {
|
||||||
let mut ctx = CompletionContext {
|
let mut ctx = CompletionContext {
|
||||||
sema,
|
sema,
|
||||||
db,
|
db,
|
||||||
|
options,
|
||||||
original_token,
|
original_token,
|
||||||
token,
|
token,
|
||||||
offset: position.offset,
|
offset: position.offset,
|
||||||
|
|
|
@ -321,14 +321,18 @@ impl Into<Vec<CompletionItem>> for Completions {
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
pub(crate) fn do_completion(code: &str, kind: CompletionKind) -> Vec<CompletionItem> {
|
pub(crate) fn do_completion(code: &str, kind: CompletionKind) -> Vec<CompletionItem> {
|
||||||
use crate::completion::completions;
|
use crate::{
|
||||||
use crate::mock_analysis::{analysis_and_position, single_file_with_position};
|
completion::{completions, CompletionOptions},
|
||||||
|
mock_analysis::{analysis_and_position, single_file_with_position},
|
||||||
|
};
|
||||||
|
|
||||||
let (analysis, position) = if code.contains("//-") {
|
let (analysis, position) = if code.contains("//-") {
|
||||||
analysis_and_position(code)
|
analysis_and_position(code)
|
||||||
} else {
|
} else {
|
||||||
single_file_with_position(code)
|
single_file_with_position(code)
|
||||||
};
|
};
|
||||||
let completions = completions(&analysis.db, position).unwrap();
|
let options = CompletionOptions::default();
|
||||||
|
let completions = completions(&analysis.db, position, &options).unwrap();
|
||||||
let completion_items: Vec<CompletionItem> = completions.into();
|
let completion_items: Vec<CompletionItem> = completions.into();
|
||||||
let mut kind_completions: Vec<CompletionItem> =
|
let mut kind_completions: Vec<CompletionItem> =
|
||||||
completion_items.into_iter().filter(|c| c.completion_kind == kind).collect();
|
completion_items.into_iter().filter(|c| c.completion_kind == kind).collect();
|
||||||
|
|
|
@ -104,10 +104,7 @@ impl Completions {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Add `<>` for generic types
|
// Add `<>` for generic types
|
||||||
if ctx.is_path_type
|
if ctx.is_path_type && !ctx.has_type_args && ctx.options.add_call_parenthesis {
|
||||||
&& !ctx.has_type_args
|
|
||||||
&& ctx.db.feature_flags.get("completion.insertion.add-call-parenthesis")
|
|
||||||
{
|
|
||||||
let has_non_default_type_params = match resolution {
|
let has_non_default_type_params = match resolution {
|
||||||
ScopeDef::ModuleDef(Adt(it)) => it.has_non_default_type_params(ctx.db),
|
ScopeDef::ModuleDef(Adt(it)) => it.has_non_default_type_params(ctx.db),
|
||||||
ScopeDef::ModuleDef(TypeAlias(it)) => it.has_non_default_type_params(ctx.db),
|
ScopeDef::ModuleDef(TypeAlias(it)) => it.has_non_default_type_params(ctx.db),
|
||||||
|
@ -212,21 +209,14 @@ impl Completions {
|
||||||
.detail(function_signature.to_string());
|
.detail(function_signature.to_string());
|
||||||
|
|
||||||
// If not an import, add parenthesis automatically.
|
// If not an import, add parenthesis automatically.
|
||||||
if ctx.use_item_syntax.is_none()
|
if ctx.use_item_syntax.is_none() && !ctx.is_call && ctx.options.add_call_parenthesis {
|
||||||
&& !ctx.is_call
|
|
||||||
&& ctx.db.feature_flags.get("completion.insertion.add-call-parenthesis")
|
|
||||||
{
|
|
||||||
tested_by!(inserts_parens_for_function_calls);
|
tested_by!(inserts_parens_for_function_calls);
|
||||||
|
|
||||||
let (snippet, label) = if params.is_empty() || has_self_param && params.len() == 1 {
|
let (snippet, label) = if params.is_empty() || has_self_param && params.len() == 1 {
|
||||||
(format!("{}()$0", name), format!("{}()", name))
|
(format!("{}()$0", name), format!("{}()", name))
|
||||||
} else {
|
} else {
|
||||||
builder = builder.trigger_call_info();
|
builder = builder.trigger_call_info();
|
||||||
let snippet = if ctx
|
let snippet = if ctx.options.add_call_argument_snippets {
|
||||||
.db
|
|
||||||
.feature_flags
|
|
||||||
.get("completion.insertion.add-argument-snippets")
|
|
||||||
{
|
|
||||||
let to_skip = if has_self_param { 1 } else { 0 };
|
let to_skip = if has_self_param { 1 } else { 0 };
|
||||||
let function_params_snippet = join(
|
let function_params_snippet = join(
|
||||||
function_signature.parameter_names.iter().skip(to_skip).enumerate().map(
|
function_signature.parameter_names.iter().skip(to_skip).enumerate().map(
|
||||||
|
|
|
@ -62,7 +62,7 @@ use crate::display::ToNav;
|
||||||
pub use crate::{
|
pub use crate::{
|
||||||
assists::{Assist, AssistId},
|
assists::{Assist, AssistId},
|
||||||
call_hierarchy::CallItem,
|
call_hierarchy::CallItem,
|
||||||
completion::{CompletionItem, CompletionItemKind, InsertTextFormat},
|
completion::{CompletionItem, CompletionItemKind, CompletionOptions, InsertTextFormat},
|
||||||
diagnostics::Severity,
|
diagnostics::Severity,
|
||||||
display::{file_structure, FunctionSignature, NavigationTarget, StructureNode},
|
display::{file_structure, FunctionSignature, NavigationTarget, StructureNode},
|
||||||
expand_macro::ExpandedMacro,
|
expand_macro::ExpandedMacro,
|
||||||
|
@ -84,7 +84,6 @@ pub use ra_db::{
|
||||||
};
|
};
|
||||||
pub use ra_ide_db::{
|
pub use ra_ide_db::{
|
||||||
change::{AnalysisChange, LibraryData},
|
change::{AnalysisChange, LibraryData},
|
||||||
feature_flags::FeatureFlags,
|
|
||||||
line_index::{LineCol, LineIndex},
|
line_index::{LineCol, LineIndex},
|
||||||
line_index_utils::translate_offset_with_edit,
|
line_index_utils::translate_offset_with_edit,
|
||||||
search::SearchScope,
|
search::SearchScope,
|
||||||
|
@ -131,13 +130,13 @@ pub struct AnalysisHost {
|
||||||
|
|
||||||
impl Default for AnalysisHost {
|
impl Default for AnalysisHost {
|
||||||
fn default() -> AnalysisHost {
|
fn default() -> AnalysisHost {
|
||||||
AnalysisHost::new(None, FeatureFlags::default())
|
AnalysisHost::new(None)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AnalysisHost {
|
impl AnalysisHost {
|
||||||
pub fn new(lru_capcity: Option<usize>, feature_flags: FeatureFlags) -> AnalysisHost {
|
pub fn new(lru_capacity: Option<usize>) -> AnalysisHost {
|
||||||
AnalysisHost { db: RootDatabase::new(lru_capcity, feature_flags) }
|
AnalysisHost { db: RootDatabase::new(lru_capacity) }
|
||||||
}
|
}
|
||||||
/// Returns a snapshot of the current state, which you can query for
|
/// Returns a snapshot of the current state, which you can query for
|
||||||
/// semantic information.
|
/// semantic information.
|
||||||
|
@ -145,10 +144,6 @@ impl AnalysisHost {
|
||||||
Analysis { db: self.db.snapshot() }
|
Analysis { db: self.db.snapshot() }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn feature_flags(&self) -> &FeatureFlags {
|
|
||||||
&self.db.feature_flags
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Applies changes to the current state of the world. If there are
|
/// Applies changes to the current state of the world. If there are
|
||||||
/// outstanding snapshots, they will be canceled.
|
/// outstanding snapshots, they will be canceled.
|
||||||
pub fn apply_change(&mut self, change: AnalysisChange) {
|
pub fn apply_change(&mut self, change: AnalysisChange) {
|
||||||
|
@ -224,11 +219,6 @@ impl Analysis {
|
||||||
(host.analysis(), file_id)
|
(host.analysis(), file_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Features for Analysis.
|
|
||||||
pub fn feature_flags(&self) -> &FeatureFlags {
|
|
||||||
&self.db.feature_flags
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Debug info about the current state of the analysis.
|
/// Debug info about the current state of the analysis.
|
||||||
pub fn status(&self) -> Cancelable<String> {
|
pub fn status(&self) -> Cancelable<String> {
|
||||||
self.with_db(|db| status::status(&*db))
|
self.with_db(|db| status::status(&*db))
|
||||||
|
@ -450,8 +440,12 @@ impl Analysis {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Computes completions at the given position.
|
/// Computes completions at the given position.
|
||||||
pub fn completions(&self, position: FilePosition) -> Cancelable<Option<Vec<CompletionItem>>> {
|
pub fn completions(
|
||||||
self.with_db(|db| completion::completions(db, position).map(Into::into))
|
&self,
|
||||||
|
position: FilePosition,
|
||||||
|
options: &CompletionOptions,
|
||||||
|
) -> Cancelable<Option<Vec<CompletionItem>>> {
|
||||||
|
self.with_db(|db| completion::completions(db, position, options).map(Into::into))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Computes assists (aka code actions aka intentions) for the given
|
/// Computes assists (aka code actions aka intentions) for the given
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
pub mod marks;
|
pub mod marks;
|
||||||
pub mod line_index;
|
pub mod line_index;
|
||||||
pub mod line_index_utils;
|
pub mod line_index_utils;
|
||||||
pub mod feature_flags;
|
|
||||||
pub mod symbol_index;
|
pub mod symbol_index;
|
||||||
pub mod change;
|
pub mod change;
|
||||||
pub mod defs;
|
pub mod defs;
|
||||||
|
@ -22,7 +21,7 @@ use ra_db::{
|
||||||
};
|
};
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
|
|
||||||
use crate::{feature_flags::FeatureFlags, line_index::LineIndex, symbol_index::SymbolsDatabase};
|
use crate::{line_index::LineIndex, symbol_index::SymbolsDatabase};
|
||||||
|
|
||||||
#[salsa::database(
|
#[salsa::database(
|
||||||
ra_db::SourceDatabaseStorage,
|
ra_db::SourceDatabaseStorage,
|
||||||
|
@ -37,7 +36,6 @@ use crate::{feature_flags::FeatureFlags, line_index::LineIndex, symbol_index::Sy
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct RootDatabase {
|
pub struct RootDatabase {
|
||||||
runtime: salsa::Runtime<RootDatabase>,
|
runtime: salsa::Runtime<RootDatabase>,
|
||||||
pub feature_flags: Arc<FeatureFlags>,
|
|
||||||
pub(crate) debug_data: Arc<DebugData>,
|
pub(crate) debug_data: Arc<DebugData>,
|
||||||
pub last_gc: crate::wasm_shims::Instant,
|
pub last_gc: crate::wasm_shims::Instant,
|
||||||
pub last_gc_check: crate::wasm_shims::Instant,
|
pub last_gc_check: crate::wasm_shims::Instant,
|
||||||
|
@ -82,17 +80,16 @@ impl salsa::Database for RootDatabase {
|
||||||
|
|
||||||
impl Default for RootDatabase {
|
impl Default for RootDatabase {
|
||||||
fn default() -> RootDatabase {
|
fn default() -> RootDatabase {
|
||||||
RootDatabase::new(None, FeatureFlags::default())
|
RootDatabase::new(None)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RootDatabase {
|
impl RootDatabase {
|
||||||
pub fn new(lru_capacity: Option<usize>, feature_flags: FeatureFlags) -> RootDatabase {
|
pub fn new(lru_capacity: Option<usize>) -> RootDatabase {
|
||||||
let mut db = RootDatabase {
|
let mut db = RootDatabase {
|
||||||
runtime: salsa::Runtime::default(),
|
runtime: salsa::Runtime::default(),
|
||||||
last_gc: crate::wasm_shims::Instant::now(),
|
last_gc: crate::wasm_shims::Instant::now(),
|
||||||
last_gc_check: crate::wasm_shims::Instant::now(),
|
last_gc_check: crate::wasm_shims::Instant::now(),
|
||||||
feature_flags: Arc::new(feature_flags),
|
|
||||||
debug_data: Default::default(),
|
debug_data: Default::default(),
|
||||||
};
|
};
|
||||||
db.set_crate_graph_with_durability(Default::default(), Durability::HIGH);
|
db.set_crate_graph_with_durability(Default::default(), Durability::HIGH);
|
||||||
|
@ -112,7 +109,6 @@ impl salsa::ParallelDatabase for RootDatabase {
|
||||||
runtime: self.runtime.snapshot(self),
|
runtime: self.runtime.snapshot(self),
|
||||||
last_gc: self.last_gc,
|
last_gc: self.last_gc,
|
||||||
last_gc_check: self.last_gc_check,
|
last_gc_check: self.last_gc_check,
|
||||||
feature_flags: Arc::clone(&self.feature_flags),
|
|
||||||
debug_data: Arc::clone(&self.debug_data),
|
debug_data: Arc::clone(&self.debug_data),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ use ra_db::{
|
||||||
salsa::{Database, Durability},
|
salsa::{Database, Durability},
|
||||||
FileId, SourceDatabaseExt,
|
FileId, SourceDatabaseExt,
|
||||||
};
|
};
|
||||||
use ra_ide::{Analysis, AnalysisChange, AnalysisHost, FilePosition, LineCol};
|
use ra_ide::{Analysis, AnalysisChange, AnalysisHost, CompletionOptions, FilePosition, LineCol};
|
||||||
|
|
||||||
use crate::cli::{load_cargo::load_cargo, Verbosity};
|
use crate::cli::{load_cargo::load_cargo, Verbosity};
|
||||||
|
|
||||||
|
@ -94,17 +94,19 @@ pub fn analysis_bench(verbosity: Verbosity, path: &Path, what: BenchWhat) -> Res
|
||||||
.analysis()
|
.analysis()
|
||||||
.file_line_index(file_id)?
|
.file_line_index(file_id)?
|
||||||
.offset(LineCol { line: pos.line - 1, col_utf16: pos.column });
|
.offset(LineCol { line: pos.line - 1, col_utf16: pos.column });
|
||||||
let file_postion = FilePosition { file_id, offset };
|
let file_position = FilePosition { file_id, offset };
|
||||||
|
|
||||||
if is_completion {
|
if is_completion {
|
||||||
let res =
|
let options = CompletionOptions::default();
|
||||||
do_work(&mut host, file_id, |analysis| analysis.completions(file_postion));
|
let res = do_work(&mut host, file_id, |analysis| {
|
||||||
|
analysis.completions(file_position, &options)
|
||||||
|
});
|
||||||
if verbosity.is_verbose() {
|
if verbosity.is_verbose() {
|
||||||
println!("\n{:#?}", res);
|
println!("\n{:#?}", res);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let res =
|
let res =
|
||||||
do_work(&mut host, file_id, |analysis| analysis.goto_definition(file_postion));
|
do_work(&mut host, file_id, |analysis| analysis.goto_definition(file_position));
|
||||||
if verbosity.is_verbose() {
|
if verbosity.is_verbose() {
|
||||||
println!("\n{:#?}", res);
|
println!("\n{:#?}", res);
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@ use std::path::Path;
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use crossbeam_channel::{unbounded, Receiver};
|
use crossbeam_channel::{unbounded, Receiver};
|
||||||
use ra_db::{CrateGraph, FileId, SourceRootId};
|
use ra_db::{CrateGraph, FileId, SourceRootId};
|
||||||
use ra_ide::{AnalysisChange, AnalysisHost, FeatureFlags};
|
use ra_ide::{AnalysisChange, AnalysisHost};
|
||||||
use ra_project_model::{get_rustc_cfg_options, PackageRoot, ProjectWorkspace};
|
use ra_project_model::{get_rustc_cfg_options, PackageRoot, ProjectWorkspace};
|
||||||
use ra_vfs::{RootEntry, Vfs, VfsChange, VfsTask, Watch};
|
use ra_vfs::{RootEntry, Vfs, VfsChange, VfsTask, Watch};
|
||||||
use rustc_hash::{FxHashMap, FxHashSet};
|
use rustc_hash::{FxHashMap, FxHashSet};
|
||||||
|
@ -82,7 +82,7 @@ pub(crate) fn load(
|
||||||
receiver: Receiver<VfsTask>,
|
receiver: Receiver<VfsTask>,
|
||||||
) -> AnalysisHost {
|
) -> AnalysisHost {
|
||||||
let lru_cap = std::env::var("RA_LRU_CAP").ok().and_then(|it| it.parse::<usize>().ok());
|
let lru_cap = std::env::var("RA_LRU_CAP").ok().and_then(|it| it.parse::<usize>().ok());
|
||||||
let mut host = AnalysisHost::new(lru_cap, FeatureFlags::default());
|
let mut host = AnalysisHost::new(lru_cap);
|
||||||
let mut analysis_change = AnalysisChange::new();
|
let mut analysis_change = AnalysisChange::new();
|
||||||
analysis_change.set_crate_graph(crate_graph);
|
analysis_change.set_crate_graph(crate_graph);
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,10 @@
|
||||||
|
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
|
|
||||||
|
// FIXME: looks like a much better design is to pass options to each call,
|
||||||
|
// rather than to have a global ambient feature flags -- that way, the clients
|
||||||
|
// can issue two successive calls with different options.
|
||||||
|
|
||||||
/// Feature flags hold fine-grained toggles for all *user-visible* features of
|
/// Feature flags hold fine-grained toggles for all *user-visible* features of
|
||||||
/// rust-analyzer.
|
/// rust-analyzer.
|
||||||
///
|
///
|
|
@ -37,6 +37,7 @@ mod config;
|
||||||
mod world;
|
mod world;
|
||||||
mod diagnostics;
|
mod diagnostics;
|
||||||
mod semantic_tokens;
|
mod semantic_tokens;
|
||||||
|
mod feature_flags;
|
||||||
|
|
||||||
use serde::de::DeserializeOwned;
|
use serde::de::DeserializeOwned;
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@ use crossbeam_channel::{select, unbounded, RecvError, Sender};
|
||||||
use lsp_server::{Connection, ErrorCode, Message, Notification, Request, RequestId, Response};
|
use lsp_server::{Connection, ErrorCode, Message, Notification, Request, RequestId, Response};
|
||||||
use lsp_types::{ClientCapabilities, NumberOrString};
|
use lsp_types::{ClientCapabilities, NumberOrString};
|
||||||
use ra_cargo_watch::{url_from_path_with_drive_lowercasing, CheckOptions, CheckTask};
|
use ra_cargo_watch::{url_from_path_with_drive_lowercasing, CheckOptions, CheckTask};
|
||||||
use ra_ide::{Canceled, FeatureFlags, FileId, LibraryData, SourceRootId};
|
use ra_ide::{Canceled, FileId, LibraryData, SourceRootId};
|
||||||
use ra_prof::profile;
|
use ra_prof::profile;
|
||||||
use ra_vfs::{VfsFile, VfsTask, Watch};
|
use ra_vfs::{VfsFile, VfsTask, Watch};
|
||||||
use relative_path::RelativePathBuf;
|
use relative_path::RelativePathBuf;
|
||||||
|
@ -28,6 +28,7 @@ use threadpool::ThreadPool;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
diagnostics::DiagnosticTask,
|
diagnostics::DiagnosticTask,
|
||||||
|
feature_flags::FeatureFlags,
|
||||||
main_loop::{
|
main_loop::{
|
||||||
pending_requests::{PendingRequest, PendingRequests},
|
pending_requests::{PendingRequest, PendingRequests},
|
||||||
subscriptions::Subscriptions,
|
subscriptions::Subscriptions,
|
||||||
|
@ -423,7 +424,7 @@ fn loop_turn(
|
||||||
{
|
{
|
||||||
loop_state.workspace_loaded = true;
|
loop_state.workspace_loaded = true;
|
||||||
let n_packages: usize = world_state.workspaces.iter().map(|it| it.n_packages()).sum();
|
let n_packages: usize = world_state.workspaces.iter().map(|it| it.n_packages()).sum();
|
||||||
if world_state.feature_flags().get("notifications.workspace-loaded") {
|
if world_state.feature_flags.get("notifications.workspace-loaded") {
|
||||||
let msg = format!("workspace loaded, {} rust packages", n_packages);
|
let msg = format!("workspace loaded, {} rust packages", n_packages);
|
||||||
show_message(req::MessageType::Info, msg, &connection.sender);
|
show_message(req::MessageType::Info, msg, &connection.sender);
|
||||||
}
|
}
|
||||||
|
@ -839,7 +840,7 @@ fn update_file_notifications_on_threadpool(
|
||||||
subscriptions: Vec<FileId>,
|
subscriptions: Vec<FileId>,
|
||||||
) {
|
) {
|
||||||
log::trace!("updating notifications for {:?}", subscriptions);
|
log::trace!("updating notifications for {:?}", subscriptions);
|
||||||
let publish_diagnostics = world.feature_flags().get("lsp.diagnostics");
|
let publish_diagnostics = world.feature_flags.get("lsp.diagnostics");
|
||||||
pool.execute(move || {
|
pool.execute(move || {
|
||||||
for file_id in subscriptions {
|
for file_id in subscriptions {
|
||||||
if publish_diagnostics {
|
if publish_diagnostics {
|
||||||
|
|
|
@ -20,8 +20,8 @@ use lsp_types::{
|
||||||
TextEdit, WorkspaceEdit,
|
TextEdit, WorkspaceEdit,
|
||||||
};
|
};
|
||||||
use ra_ide::{
|
use ra_ide::{
|
||||||
Assist, AssistId, FileId, FilePosition, FileRange, Query, RangeInfo, Runnable, RunnableKind,
|
Assist, AssistId, CompletionOptions, FileId, FilePosition, FileRange, Query, RangeInfo,
|
||||||
SearchScope,
|
Runnable, RunnableKind, SearchScope,
|
||||||
};
|
};
|
||||||
use ra_prof::profile;
|
use ra_prof::profile;
|
||||||
use ra_syntax::{AstNode, SyntaxKind, TextRange, TextUnit};
|
use ra_syntax::{AstNode, SyntaxKind, TextRange, TextUnit};
|
||||||
|
@ -424,7 +424,15 @@ pub fn handle_completion(
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
}
|
}
|
||||||
|
|
||||||
let items = match world.analysis().completions(position)? {
|
let options = CompletionOptions {
|
||||||
|
enable_postfix_completions: world.feature_flags.get("completion.enable-postfix"),
|
||||||
|
add_call_parenthesis: world.feature_flags.get("completion.insertion.add-call-parenthesis"),
|
||||||
|
add_call_argument_snippets: world
|
||||||
|
.feature_flags
|
||||||
|
.get("completion.insertion.add-argument-snippets"),
|
||||||
|
};
|
||||||
|
|
||||||
|
let items = match world.analysis().completions(position, &options)? {
|
||||||
None => return Ok(None),
|
None => return Ok(None),
|
||||||
Some(items) => items,
|
Some(items) => items,
|
||||||
};
|
};
|
||||||
|
@ -461,7 +469,7 @@ pub fn handle_signature_help(
|
||||||
let _p = profile("handle_signature_help");
|
let _p = profile("handle_signature_help");
|
||||||
let position = params.try_conv_with(&world)?;
|
let position = params.try_conv_with(&world)?;
|
||||||
if let Some(call_info) = world.analysis().call_info(position)? {
|
if let Some(call_info) = world.analysis().call_info(position)? {
|
||||||
let concise = !world.analysis().feature_flags().get("call-info.full");
|
let concise = !world.feature_flags.get("call-info.full");
|
||||||
let mut active_parameter = call_info.active_parameter.map(|it| it as i64);
|
let mut active_parameter = call_info.active_parameter.map(|it| it as i64);
|
||||||
if concise && call_info.signature.has_self_param {
|
if concise && call_info.signature.has_self_param {
|
||||||
active_parameter = active_parameter.map(|it| it.saturating_sub(1));
|
active_parameter = active_parameter.map(|it| it.saturating_sub(1));
|
||||||
|
|
|
@ -13,8 +13,7 @@ use lsp_types::Url;
|
||||||
use parking_lot::RwLock;
|
use parking_lot::RwLock;
|
||||||
use ra_cargo_watch::{url_from_path_with_drive_lowercasing, CheckOptions, CheckWatcher};
|
use ra_cargo_watch::{url_from_path_with_drive_lowercasing, CheckOptions, CheckWatcher};
|
||||||
use ra_ide::{
|
use ra_ide::{
|
||||||
Analysis, AnalysisChange, AnalysisHost, CrateGraph, FeatureFlags, FileId, LibraryData,
|
Analysis, AnalysisChange, AnalysisHost, CrateGraph, FileId, LibraryData, SourceRootId,
|
||||||
SourceRootId,
|
|
||||||
};
|
};
|
||||||
use ra_project_model::{get_rustc_cfg_options, ProjectWorkspace};
|
use ra_project_model::{get_rustc_cfg_options, ProjectWorkspace};
|
||||||
use ra_vfs::{LineEndings, RootEntry, Vfs, VfsChange, VfsFile, VfsRoot, VfsTask, Watch};
|
use ra_vfs::{LineEndings, RootEntry, Vfs, VfsChange, VfsFile, VfsRoot, VfsTask, Watch};
|
||||||
|
@ -22,6 +21,7 @@ use relative_path::RelativePathBuf;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
diagnostics::{CheckFixes, DiagnosticCollection},
|
diagnostics::{CheckFixes, DiagnosticCollection},
|
||||||
|
feature_flags::FeatureFlags,
|
||||||
main_loop::pending_requests::{CompletedRequest, LatestRequests},
|
main_loop::pending_requests::{CompletedRequest, LatestRequests},
|
||||||
vfs_glob::{Glob, RustPackageFilterBuilder},
|
vfs_glob::{Glob, RustPackageFilterBuilder},
|
||||||
LspError, Result,
|
LspError, Result,
|
||||||
|
@ -45,6 +45,7 @@ pub struct Options {
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct WorldState {
|
pub struct WorldState {
|
||||||
pub options: Options,
|
pub options: Options,
|
||||||
|
pub feature_flags: Arc<FeatureFlags>,
|
||||||
//FIXME: this belongs to `LoopState` rather than to `WorldState`
|
//FIXME: this belongs to `LoopState` rather than to `WorldState`
|
||||||
pub roots_to_scan: usize,
|
pub roots_to_scan: usize,
|
||||||
pub roots: Vec<PathBuf>,
|
pub roots: Vec<PathBuf>,
|
||||||
|
@ -60,6 +61,7 @@ pub struct WorldState {
|
||||||
/// An immutable snapshot of the world's state at a point in time.
|
/// An immutable snapshot of the world's state at a point in time.
|
||||||
pub struct WorldSnapshot {
|
pub struct WorldSnapshot {
|
||||||
pub options: Options,
|
pub options: Options,
|
||||||
|
pub feature_flags: Arc<FeatureFlags>,
|
||||||
pub workspaces: Arc<Vec<ProjectWorkspace>>,
|
pub workspaces: Arc<Vec<ProjectWorkspace>>,
|
||||||
pub analysis: Analysis,
|
pub analysis: Analysis,
|
||||||
pub latest_requests: Arc<RwLock<LatestRequests>>,
|
pub latest_requests: Arc<RwLock<LatestRequests>>,
|
||||||
|
@ -146,10 +148,11 @@ impl WorldState {
|
||||||
CheckWatcher::dummy()
|
CheckWatcher::dummy()
|
||||||
});
|
});
|
||||||
|
|
||||||
let mut analysis_host = AnalysisHost::new(lru_capacity, feature_flags);
|
let mut analysis_host = AnalysisHost::new(lru_capacity);
|
||||||
analysis_host.apply_change(change);
|
analysis_host.apply_change(change);
|
||||||
WorldState {
|
WorldState {
|
||||||
options,
|
options,
|
||||||
|
feature_flags: Arc::new(feature_flags),
|
||||||
roots_to_scan,
|
roots_to_scan,
|
||||||
roots: folder_roots,
|
roots: folder_roots,
|
||||||
workspaces: Arc::new(workspaces),
|
workspaces: Arc::new(workspaces),
|
||||||
|
@ -216,6 +219,7 @@ impl WorldState {
|
||||||
pub fn snapshot(&self) -> WorldSnapshot {
|
pub fn snapshot(&self) -> WorldSnapshot {
|
||||||
WorldSnapshot {
|
WorldSnapshot {
|
||||||
options: self.options.clone(),
|
options: self.options.clone(),
|
||||||
|
feature_flags: Arc::clone(&self.feature_flags),
|
||||||
workspaces: Arc::clone(&self.workspaces),
|
workspaces: Arc::clone(&self.workspaces),
|
||||||
analysis: self.analysis_host.analysis(),
|
analysis: self.analysis_host.analysis(),
|
||||||
vfs: Arc::clone(&self.vfs),
|
vfs: Arc::clone(&self.vfs),
|
||||||
|
@ -235,10 +239,6 @@ impl WorldState {
|
||||||
pub fn complete_request(&mut self, request: CompletedRequest) {
|
pub fn complete_request(&mut self, request: CompletedRequest) {
|
||||||
self.latest_requests.write().record(request)
|
self.latest_requests.write().record(request)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn feature_flags(&self) -> &FeatureFlags {
|
|
||||||
self.analysis_host.feature_flags()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WorldSnapshot {
|
impl WorldSnapshot {
|
||||||
|
@ -306,8 +306,4 @@ impl WorldSnapshot {
|
||||||
let path = self.vfs.read().file2path(VfsFile(file_id.0));
|
let path = self.vfs.read().file2path(VfsFile(file_id.0));
|
||||||
self.workspaces.iter().find_map(|ws| ws.workspace_root_for(&path))
|
self.workspaces.iter().find_map(|ws| ws.workspace_root_for(&path))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn feature_flags(&self) -> &FeatureFlags {
|
|
||||||
self.analysis.feature_flags()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue