From f8a056117898c56d34d1758455bc54df50e2e426 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 6 Jan 2021 20:43:46 +0300 Subject: [PATCH] Align config's API with usage The config now is mostly immutable, optimize for that. --- crates/assists/src/assist_config.rs | 32 +-------- crates/assists/src/assist_context.rs | 10 +-- .../assists/src/handlers/generate_function.rs | 3 +- crates/assists/src/lib.rs | 2 +- crates/assists/src/tests.rs | 38 +++++++---- crates/assists/src/utils.rs | 7 +- crates/completion/src/completions/postfix.rs | 5 +- .../src/completions/postfix/format_like.rs | 7 +- crates/completion/src/completions/snippet.rs | 6 +- .../src/completions/unqualified_path.rs | 18 +++-- crates/completion/src/config.rs | 26 +------ crates/completion/src/item.rs | 4 +- crates/completion/src/lib.rs | 7 +- crates/completion/src/render.rs | 12 ++-- crates/completion/src/render/function.rs | 4 +- crates/completion/src/render/pattern.rs | 6 +- crates/completion/src/test_utils.rs | 22 ++++-- crates/ide/src/lib.rs | 2 +- crates/ide_db/src/helpers.rs | 20 +++++- .../rust-analyzer/src/cli/analysis_bench.rs | 18 +++-- crates/rust-analyzer/src/config.rs | 67 ++++++++++--------- crates/rust-analyzer/src/to_proto.rs | 10 ++- 22 files changed, 164 insertions(+), 162 deletions(-) diff --git a/crates/assists/src/assist_config.rs b/crates/assists/src/assist_config.rs index c458d90541..4fe8ea7614 100644 --- a/crates/assists/src/assist_config.rs +++ b/crates/assists/src/assist_config.rs @@ -4,8 +4,7 @@ //! module, and we use to statically check that we only produce snippet //! assists if we are allowed to. -use hir::PrefixKind; -use ide_db::helpers::insert_use::MergeBehavior; +use ide_db::helpers::{insert_use::MergeBehavior, SnippetCap}; use crate::AssistKind; @@ -16,35 +15,8 @@ pub struct AssistConfig { pub insert_use: InsertUseConfig, } -impl AssistConfig { - pub fn allow_snippets(&mut self, yes: bool) { - self.snippet_cap = if yes { Some(SnippetCap { _private: () }) } else { None } - } -} - -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -pub struct SnippetCap { - _private: (), -} - -impl Default for AssistConfig { - fn default() -> Self { - AssistConfig { - snippet_cap: Some(SnippetCap { _private: () }), - allowed: None, - insert_use: InsertUseConfig::default(), - } - } -} - #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub struct InsertUseConfig { pub merge: Option, - pub prefix_kind: PrefixKind, -} - -impl Default for InsertUseConfig { - fn default() -> Self { - InsertUseConfig { merge: Some(MergeBehavior::Full), prefix_kind: PrefixKind::Plain } - } + pub prefix_kind: hir::PrefixKind, } diff --git a/crates/assists/src/assist_context.rs b/crates/assists/src/assist_context.rs index 4f59d39a96..91cc634272 100644 --- a/crates/assists/src/assist_context.rs +++ b/crates/assists/src/assist_context.rs @@ -4,7 +4,10 @@ use std::mem; use algo::find_covering_element; use hir::Semantics; -use ide_db::base_db::{AnchoredPathBuf, FileId, FileRange}; +use ide_db::{ + base_db::{AnchoredPathBuf, FileId, FileRange}, + helpers::SnippetCap, +}; use ide_db::{ label::Label, source_change::{FileSystemEdit, SourceChange, SourceFileEdit}, @@ -17,10 +20,7 @@ use syntax::{ }; use text_edit::{TextEdit, TextEditBuilder}; -use crate::{ - assist_config::{AssistConfig, SnippetCap}, - Assist, AssistId, AssistKind, GroupLabel, -}; +use crate::{assist_config::AssistConfig, Assist, AssistId, AssistKind, GroupLabel}; /// `AssistContext` allows to apply an assist or check if it could be applied. /// diff --git a/crates/assists/src/handlers/generate_function.rs b/crates/assists/src/handlers/generate_function.rs index f4cf155b63..d169abedb4 100644 --- a/crates/assists/src/handlers/generate_function.rs +++ b/crates/assists/src/handlers/generate_function.rs @@ -1,5 +1,5 @@ use hir::HirDisplay; -use ide_db::base_db::FileId; +use ide_db::{base_db::FileId, helpers::SnippetCap}; use rustc_hash::{FxHashMap, FxHashSet}; use syntax::{ ast::{ @@ -11,7 +11,6 @@ use syntax::{ }; use crate::{ - assist_config::SnippetCap, utils::{render_snippet, Cursor}, AssistContext, AssistId, AssistKind, Assists, }; diff --git a/crates/assists/src/lib.rs b/crates/assists/src/lib.rs index 5e3a1b3683..90009c55a8 100644 --- a/crates/assists/src/lib.rs +++ b/crates/assists/src/lib.rs @@ -24,7 +24,7 @@ use syntax::TextRange; pub(crate) use crate::assist_context::{AssistContext, Assists}; -pub use assist_config::AssistConfig; +pub use assist_config::{AssistConfig, InsertUseConfig}; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum AssistKind { diff --git a/crates/assists/src/tests.rs b/crates/assists/src/tests.rs index 21e448fb86..a4c6a7570e 100644 --- a/crates/assists/src/tests.rs +++ b/crates/assists/src/tests.rs @@ -1,15 +1,29 @@ mod generated; use hir::Semantics; -use ide_db::base_db::{fixture::WithFixture, FileId, FileRange, SourceDatabaseExt}; -use ide_db::source_change::FileSystemEdit; -use ide_db::RootDatabase; +use ide_db::{ + base_db::{fixture::WithFixture, FileId, FileRange, SourceDatabaseExt}, + helpers::{insert_use::MergeBehavior, SnippetCap}, + source_change::FileSystemEdit, + RootDatabase, +}; use syntax::TextRange; use test_utils::{assert_eq_text, extract_offset, extract_range}; -use crate::{handlers::Handler, Assist, AssistConfig, AssistContext, AssistKind, Assists}; +use crate::{ + handlers::Handler, Assist, AssistConfig, AssistContext, AssistKind, Assists, InsertUseConfig, +}; use stdx::{format_to, trim_indent}; +pub(crate) const TEST_CONFIG: AssistConfig = AssistConfig { + snippet_cap: SnippetCap::new(true), + allowed: None, + insert_use: InsertUseConfig { + merge: Some(MergeBehavior::Full), + prefix_kind: hir::PrefixKind::Plain, + }, +}; + pub(crate) fn with_single_file(text: &str) -> (RootDatabase, FileId) { RootDatabase::with_single_file(text) } @@ -48,14 +62,14 @@ fn check_doc_test(assist_id: &str, before: &str, after: &str) { let before = db.file_text(file_id).to_string(); let frange = FileRange { file_id, range: selection.into() }; - let assist = Assist::get(&db, &AssistConfig::default(), true, frange) + let assist = Assist::get(&db, &TEST_CONFIG, true, frange) .into_iter() .find(|assist| assist.id.0 == assist_id) .unwrap_or_else(|| { panic!( "\n\nAssist is not applicable: {}\nAvailable assists: {}", assist_id, - Assist::get(&db, &AssistConfig::default(), false, frange) + Assist::get(&db, &TEST_CONFIG, false, frange) .into_iter() .map(|assist| assist.id.0) .collect::>() @@ -89,7 +103,7 @@ fn check(handler: Handler, before: &str, expected: ExpectedResult, assist_label: let frange = FileRange { file_id: file_with_caret_id, range: range_or_offset.into() }; let sema = Semantics::new(&db); - let config = AssistConfig::default(); + let config = TEST_CONFIG; let ctx = AssistContext::new(sema, &config, frange); let mut acc = Assists::new(&ctx, true); handler(&mut acc, &ctx); @@ -156,7 +170,7 @@ fn assist_order_field_struct() { let (before_cursor_pos, before) = extract_offset(before); let (db, file_id) = with_single_file(&before); let frange = FileRange { file_id, range: TextRange::empty(before_cursor_pos) }; - let assists = Assist::get(&db, &AssistConfig::default(), false, frange); + let assists = Assist::get(&db, &TEST_CONFIG, false, frange); let mut assists = assists.iter(); assert_eq!(assists.next().expect("expected assist").label, "Change visibility to pub(crate)"); @@ -176,7 +190,7 @@ fn assist_order_if_expr() { let (range, before) = extract_range(before); let (db, file_id) = with_single_file(&before); let frange = FileRange { file_id, range }; - let assists = Assist::get(&db, &AssistConfig::default(), false, frange); + let assists = Assist::get(&db, &TEST_CONFIG, false, frange); let mut assists = assists.iter(); assert_eq!(assists.next().expect("expected assist").label, "Extract into variable"); @@ -198,7 +212,7 @@ fn assist_filter_works() { let frange = FileRange { file_id, range }; { - let mut cfg = AssistConfig::default(); + let mut cfg = TEST_CONFIG; cfg.allowed = Some(vec![AssistKind::Refactor]); let assists = Assist::get(&db, &cfg, false, frange); @@ -209,7 +223,7 @@ fn assist_filter_works() { } { - let mut cfg = AssistConfig::default(); + let mut cfg = TEST_CONFIG; cfg.allowed = Some(vec![AssistKind::RefactorExtract]); let assists = Assist::get(&db, &cfg, false, frange); assert_eq!(assists.len(), 1); @@ -219,7 +233,7 @@ fn assist_filter_works() { } { - let mut cfg = AssistConfig::default(); + let mut cfg = TEST_CONFIG; cfg.allowed = Some(vec![AssistKind::QuickFix]); let assists = Assist::get(&db, &cfg, false, frange); assert!(assists.is_empty(), "All asserts but quickfixes should be filtered out"); diff --git a/crates/assists/src/utils.rs b/crates/assists/src/utils.rs index 8212cd1292..9ea96eb73b 100644 --- a/crates/assists/src/utils.rs +++ b/crates/assists/src/utils.rs @@ -4,7 +4,7 @@ pub(crate) mod import_assets; use std::ops; use hir::HasSource; -use ide_db::RootDatabase; +use ide_db::{helpers::SnippetCap, RootDatabase}; use itertools::Itertools; use syntax::{ ast::edit::AstNodeEdit, @@ -16,10 +16,7 @@ use syntax::{ SyntaxNode, TextSize, T, }; -use crate::{ - assist_config::SnippetCap, - ast_transform::{self, AstTransform, QualifyPaths, SubstituteTypeParams}, -}; +use crate::ast_transform::{self, AstTransform, QualifyPaths, SubstituteTypeParams}; pub(crate) fn unwrap_trivial_block(block: ast::BlockExpr) -> ast::Expr { extract_trivial_expression(&block) diff --git a/crates/completion/src/completions/postfix.rs b/crates/completion/src/completions/postfix.rs index 3883d6d214..4888f518ac 100644 --- a/crates/completion/src/completions/postfix.rs +++ b/crates/completion/src/completions/postfix.rs @@ -2,7 +2,7 @@ mod format_like; -use ide_db::ty_filter::TryEnum; +use ide_db::{helpers::SnippetCap, ty_filter::TryEnum}; use syntax::{ ast::{self, AstNode, AstToken}, SyntaxKind::{BLOCK_EXPR, EXPR_STMT}, @@ -10,9 +10,8 @@ use syntax::{ }; use text_edit::TextEdit; -use self::format_like::add_format_like_completions; use crate::{ - config::SnippetCap, + completions::postfix::format_like::add_format_like_completions, context::CompletionContext, item::{Builder, CompletionKind}, CompletionItem, CompletionItemKind, Completions, diff --git a/crates/completion/src/completions/postfix/format_like.rs b/crates/completion/src/completions/postfix/format_like.rs index def4b13fba..3afc630210 100644 --- a/crates/completion/src/completions/postfix/format_like.rs +++ b/crates/completion/src/completions/postfix/format_like.rs @@ -14,12 +14,11 @@ // + `logw` -> `log::warn!(...)` // + `loge` -> `log::error!(...)` -use crate::{ - completions::postfix::postfix_snippet, config::SnippetCap, context::CompletionContext, - Completions, -}; +use ide_db::helpers::SnippetCap; use syntax::ast::{self, AstToken}; +use crate::{completions::postfix::postfix_snippet, context::CompletionContext, Completions}; + /// Mapping ("postfix completion item" => "macro to use") static KINDS: &[(&str, &str)] = &[ ("format", "format!"), diff --git a/crates/completion/src/completions/snippet.rs b/crates/completion/src/completions/snippet.rs index 8425901300..b5e7046962 100644 --- a/crates/completion/src/completions/snippet.rs +++ b/crates/completion/src/completions/snippet.rs @@ -1,8 +1,10 @@ //! This file provides snippet completions, like `pd` => `eprintln!(...)`. +use ide_db::helpers::SnippetCap; + use crate::{ - config::SnippetCap, item::Builder, CompletionContext, CompletionItem, CompletionItemKind, - CompletionKind, Completions, + item::Builder, CompletionContext, CompletionItem, CompletionItemKind, CompletionKind, + Completions, }; fn snippet(ctx: &CompletionContext, cap: SnippetCap, label: &str, snippet: &str) -> Builder { diff --git a/crates/completion/src/completions/unqualified_path.rs b/crates/completion/src/completions/unqualified_path.rs index 896f167ffa..2da21b5c26 100644 --- a/crates/completion/src/completions/unqualified_path.rs +++ b/crates/completion/src/completions/unqualified_path.rs @@ -192,12 +192,14 @@ mod tests { use test_utils::mark; use crate::{ - test_utils::{check_edit, check_edit_with_config, completion_list_with_config}, + test_utils::{ + check_edit, check_edit_with_config, completion_list_with_config, TEST_CONFIG, + }, CompletionConfig, CompletionKind, }; fn check(ra_fixture: &str, expect: Expect) { - check_with_config(CompletionConfig::default(), ra_fixture, expect); + check_with_config(TEST_CONFIG, ra_fixture, expect); } fn check_with_config(config: CompletionConfig, ra_fixture: &str, expect: Expect) { @@ -205,10 +207,6 @@ mod tests { expect.assert_eq(&actual) } - fn fuzzy_completion_config() -> CompletionConfig { - CompletionConfig::default() - } - #[test] fn self_fulfilling_completion() { mark::check!(self_fulfilling_completion); @@ -832,7 +830,7 @@ impl My<|> #[test] fn function_fuzzy_completion() { check_edit_with_config( - fuzzy_completion_config(), + TEST_CONFIG, "stdin", r#" //- /lib.rs crate:dep @@ -858,7 +856,7 @@ fn main() { #[test] fn macro_fuzzy_completion() { check_edit_with_config( - fuzzy_completion_config(), + TEST_CONFIG, "macro_with_curlies!", r#" //- /lib.rs crate:dep @@ -886,7 +884,7 @@ fn main() { #[test] fn struct_fuzzy_completion() { check_edit_with_config( - fuzzy_completion_config(), + TEST_CONFIG, "ThirdStruct", r#" //- /lib.rs crate:dep @@ -917,7 +915,7 @@ fn main() { fn fuzzy_completions_come_in_specific_order() { mark::check!(certain_fuzzy_order_test); check_with_config( - fuzzy_completion_config(), + TEST_CONFIG, r#" //- /lib.rs crate:dep pub struct FirstStruct; diff --git a/crates/completion/src/config.rs b/crates/completion/src/config.rs index 9f82b03466..b4439b7d14 100644 --- a/crates/completion/src/config.rs +++ b/crates/completion/src/config.rs @@ -4,7 +4,7 @@ //! module, and we use to statically check that we only produce snippet //! completions if we are allowed to. -use ide_db::helpers::insert_use::MergeBehavior; +use ide_db::helpers::{insert_use::MergeBehavior, SnippetCap}; #[derive(Clone, Debug, PartialEq, Eq)] pub struct CompletionConfig { @@ -15,27 +15,3 @@ pub struct CompletionConfig { pub snippet_cap: Option, pub merge: Option, } - -impl CompletionConfig { - pub fn allow_snippets(&mut self, yes: bool) { - self.snippet_cap = if yes { Some(SnippetCap { _private: () }) } else { None } - } -} - -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -pub struct SnippetCap { - _private: (), -} - -impl Default for CompletionConfig { - fn default() -> Self { - CompletionConfig { - enable_postfix_completions: true, - enable_autoimport_completions: true, - add_call_parenthesis: true, - add_call_argument_snippets: true, - snippet_cap: Some(SnippetCap { _private: () }), - merge: Some(MergeBehavior::Full), - } - } -} diff --git a/crates/completion/src/item.rs b/crates/completion/src/item.rs index 65f8353e7c..7087fae37c 100644 --- a/crates/completion/src/item.rs +++ b/crates/completion/src/item.rs @@ -5,13 +5,11 @@ use std::fmt; use hir::{Documentation, ModPath, Mutability}; use ide_db::helpers::{ insert_use::{self, ImportScope, MergeBehavior}, - mod_path_to_ast, + mod_path_to_ast, SnippetCap, }; use syntax::{algo, TextRange}; use text_edit::TextEdit; -use crate::config::SnippetCap; - /// `CompletionItem` describes a single completion variant in the editor pop-up. /// It is basically a POD with various properties. To construct a /// `CompletionItem`, use `new` method and the `Builder` struct. diff --git a/crates/completion/src/lib.rs b/crates/completion/src/lib.rs index 366aced714..3c7d5a46cf 100644 --- a/crates/completion/src/lib.rs +++ b/crates/completion/src/lib.rs @@ -158,8 +158,7 @@ pub fn resolve_completion_edits( #[cfg(test)] mod tests { - use crate::config::CompletionConfig; - use crate::test_utils; + use crate::test_utils::{self, TEST_CONFIG}; struct DetailAndDocumentation<'a> { detail: &'a str, @@ -168,7 +167,7 @@ mod tests { fn check_detail_and_documentation(ra_fixture: &str, expected: DetailAndDocumentation) { let (db, position) = test_utils::position(ra_fixture); - let config = CompletionConfig::default(); + let config = TEST_CONFIG; let completions: Vec<_> = crate::completions(&db, &config, position).unwrap().into(); for item in completions { if item.detail() == Some(expected.detail) { @@ -183,7 +182,7 @@ mod tests { fn check_no_completion(ra_fixture: &str) { let (db, position) = test_utils::position(ra_fixture); - let config = CompletionConfig::default(); + let config = TEST_CONFIG; let completions: Option> = crate::completions(&db, &config, position) .and_then(|completions| { diff --git a/crates/completion/src/render.rs b/crates/completion/src/render.rs index ac0b2a5139..7554c15651 100644 --- a/crates/completion/src/render.rs +++ b/crates/completion/src/render.rs @@ -11,13 +11,13 @@ pub(crate) mod type_alias; mod builder_ext; use hir::{Documentation, HasAttrs, HirDisplay, Mutability, ScopeDef, Type}; -use ide_db::RootDatabase; +use ide_db::{helpers::SnippetCap, RootDatabase}; use syntax::TextRange; use test_utils::mark; use crate::{ - config::SnippetCap, item::ImportEdit, CompletionContext, CompletionItem, CompletionItemKind, - CompletionKind, CompletionScore, + item::ImportEdit, CompletionContext, CompletionItem, CompletionItemKind, CompletionKind, + CompletionScore, }; use crate::render::{enum_variant::render_variant, function::render_fn, macro_::render_macro}; @@ -320,8 +320,8 @@ mod tests { use test_utils::mark; use crate::{ - test_utils::{check_edit, do_completion, get_all_items}, - CompletionConfig, CompletionKind, CompletionScore, + test_utils::{check_edit, do_completion, get_all_items, TEST_CONFIG}, + CompletionKind, CompletionScore, }; fn check(ra_fixture: &str, expect: Expect) { @@ -338,7 +338,7 @@ mod tests { } } - let mut completions = get_all_items(CompletionConfig::default(), ra_fixture); + let mut completions = get_all_items(TEST_CONFIG, ra_fixture); completions.sort_by_key(|it| (Reverse(it.score()), it.label().to_string())); let actual = completions .into_iter() diff --git a/crates/completion/src/render/function.rs b/crates/completion/src/render/function.rs index 081be14f4e..7b2f62b4b4 100644 --- a/crates/completion/src/render/function.rs +++ b/crates/completion/src/render/function.rs @@ -113,7 +113,7 @@ mod tests { use test_utils::mark; use crate::{ - test_utils::{check_edit, check_edit_with_config}, + test_utils::{check_edit, check_edit_with_config, TEST_CONFIG}, CompletionConfig, }; @@ -211,7 +211,7 @@ fn main() { S::foo(${1:&self})$0 } fn suppress_arg_snippets() { mark::check!(suppress_arg_snippets); check_edit_with_config( - CompletionConfig { add_call_argument_snippets: false, ..CompletionConfig::default() }, + CompletionConfig { add_call_argument_snippets: false, ..TEST_CONFIG }, "with_args", r#" fn with_args(x: i32, y: String) {} diff --git a/crates/completion/src/render/pattern.rs b/crates/completion/src/render/pattern.rs index a3b6a3cac7..61d8a17e56 100644 --- a/crates/completion/src/render/pattern.rs +++ b/crates/completion/src/render/pattern.rs @@ -1,12 +1,10 @@ //! Renderer for patterns. use hir::{db::HirDatabase, HasAttrs, HasVisibility, Name, StructKind}; +use ide_db::helpers::SnippetCap; use itertools::Itertools; -use crate::{ - config::SnippetCap, item::CompletionKind, render::RenderContext, CompletionItem, - CompletionItemKind, -}; +use crate::{item::CompletionKind, render::RenderContext, CompletionItem, CompletionItemKind}; fn visible_fields( ctx: &RenderContext<'_>, diff --git a/crates/completion/src/test_utils.rs b/crates/completion/src/test_utils.rs index eb0c16f52b..b5e296777e 100644 --- a/crates/completion/src/test_utils.rs +++ b/crates/completion/src/test_utils.rs @@ -1,8 +1,11 @@ //! Runs completion for testing purposes. use hir::Semantics; -use ide_db::base_db::{fixture::ChangeFixture, FileLoader, FilePosition}; -use ide_db::RootDatabase; +use ide_db::{ + base_db::{fixture::ChangeFixture, FileLoader, FilePosition}, + helpers::{insert_use::MergeBehavior, SnippetCap}, + RootDatabase, +}; use itertools::Itertools; use stdx::{format_to, trim_indent}; use syntax::{AstNode, NodeOrToken, SyntaxElement}; @@ -10,6 +13,15 @@ use test_utils::{assert_eq_text, RangeOrOffset}; use crate::{item::CompletionKind, CompletionConfig, CompletionItem}; +pub(crate) const TEST_CONFIG: CompletionConfig = CompletionConfig { + enable_postfix_completions: true, + enable_autoimport_completions: true, + add_call_parenthesis: true, + add_call_argument_snippets: true, + snippet_cap: SnippetCap::new(true), + merge: Some(MergeBehavior::Full), +}; + /// Creates analysis from a multi-file fixture, returns positions marked with <|>. pub(crate) fn position(ra_fixture: &str) -> (RootDatabase, FilePosition) { let change_fixture = ChangeFixture::parse(ra_fixture); @@ -24,7 +36,7 @@ pub(crate) fn position(ra_fixture: &str) -> (RootDatabase, FilePosition) { } pub(crate) fn do_completion(code: &str, kind: CompletionKind) -> Vec { - do_completion_with_config(CompletionConfig::default(), code, kind) + do_completion_with_config(TEST_CONFIG, code, kind) } pub(crate) fn do_completion_with_config( @@ -39,7 +51,7 @@ pub(crate) fn do_completion_with_config( } pub(crate) fn completion_list(code: &str, kind: CompletionKind) -> String { - completion_list_with_config(CompletionConfig::default(), code, kind) + completion_list_with_config(TEST_CONFIG, code, kind) } pub(crate) fn completion_list_with_config( @@ -76,7 +88,7 @@ fn monospace_width(s: &str) -> usize { } pub(crate) fn check_edit(what: &str, ra_fixture_before: &str, ra_fixture_after: &str) { - check_edit_with_config(CompletionConfig::default(), what, ra_fixture_before, ra_fixture_after) + check_edit_with_config(TEST_CONFIG, what, ra_fixture_before, ra_fixture_after) } pub(crate) fn check_edit_with_config( diff --git a/crates/ide/src/lib.rs b/crates/ide/src/lib.rs index 72c8bfd092..cea2a13c8e 100644 --- a/crates/ide/src/lib.rs +++ b/crates/ide/src/lib.rs @@ -80,7 +80,7 @@ pub use crate::{ HighlightedRange, }, }; -pub use assists::{Assist, AssistConfig, AssistId, AssistKind}; +pub use assists::{Assist, AssistConfig, AssistId, AssistKind, InsertUseConfig}; pub use completion::{ CompletionConfig, CompletionItem, CompletionItemKind, CompletionScore, ImportEdit, InsertTextFormat, diff --git a/crates/ide_db/src/helpers.rs b/crates/ide_db/src/helpers.rs index d988588ff3..e3e5670f18 100644 --- a/crates/ide_db/src/helpers.rs +++ b/crates/ide_db/src/helpers.rs @@ -1,9 +1,10 @@ //! A module with ide helpers for high-level ide features. -use crate::RootDatabase; +pub mod insert_use; + use hir::{Crate, Enum, Module, ScopeDef, Semantics, Trait}; use syntax::ast::{self, make}; -pub mod insert_use; +use crate::RootDatabase; /// Converts the mod path struct into its ast representation. pub fn mod_path_to_ast(path: &hir::ModPath) -> ast::Path { @@ -201,3 +202,18 @@ pub use prelude::*; Some(def) } } + +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub struct SnippetCap { + _private: (), +} + +impl SnippetCap { + pub const fn new(allow_snippets: bool) -> Option { + if allow_snippets { + Some(SnippetCap { _private: () }) + } else { + None + } + } +} diff --git a/crates/rust-analyzer/src/cli/analysis_bench.rs b/crates/rust-analyzer/src/cli/analysis_bench.rs index 5a8484c624..7d3fda7a84 100644 --- a/crates/rust-analyzer/src/cli/analysis_bench.rs +++ b/crates/rust-analyzer/src/cli/analysis_bench.rs @@ -6,9 +6,12 @@ use anyhow::{bail, format_err, Result}; use ide::{ Analysis, AnalysisHost, Change, CompletionConfig, DiagnosticsConfig, FilePosition, LineCol, }; -use ide_db::base_db::{ - salsa::{Database, Durability}, - FileId, +use ide_db::{ + base_db::{ + salsa::{Database, Durability}, + FileId, + }, + helpers::SnippetCap, }; use vfs::AbsPathBuf; @@ -87,7 +90,14 @@ impl BenchCmd { let file_position = FilePosition { file_id, offset }; if is_completion { - let options = CompletionConfig::default(); + let options = CompletionConfig { + enable_postfix_completions: true, + enable_autoimport_completions: true, + add_call_parenthesis: true, + add_call_argument_snippets: true, + snippet_cap: SnippetCap::new(true), + merge: None, + }; let res = do_work(&mut host, file_id, |analysis| { analysis.completions(&options, file_position) }); diff --git a/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs index ce95263156..e3ba81ac6d 100644 --- a/crates/rust-analyzer/src/config.rs +++ b/crates/rust-analyzer/src/config.rs @@ -11,8 +11,11 @@ use std::{convert::TryFrom, ffi::OsString, path::PathBuf}; use flycheck::FlycheckConfig; use hir::PrefixKind; -use ide::{AssistConfig, CompletionConfig, DiagnosticsConfig, HoverConfig, InlayHintsConfig}; -use ide_db::helpers::insert_use::MergeBehavior; +use ide::{ + AssistConfig, CompletionConfig, DiagnosticsConfig, HoverConfig, InlayHintsConfig, + InsertUseConfig, +}; +use ide_db::helpers::{insert_use::MergeBehavior, SnippetCap}; use itertools::Itertools; use lsp_types::{ClientCapabilities, MarkupKind}; use project_model::{CargoConfig, ProjectJson, ProjectJsonData, ProjectManifest}; @@ -534,37 +537,39 @@ impl Config { } } pub fn completion(&self) -> CompletionConfig { - let mut res = CompletionConfig::default(); - res.enable_postfix_completions = self.data.completion_postfix_enable; - res.enable_autoimport_completions = - self.data.completion_autoimport_enable && completion_item_edit_resolve(&self.caps); - res.add_call_parenthesis = self.data.completion_addCallParenthesis; - res.add_call_argument_snippets = self.data.completion_addCallArgumentSnippets; - res.merge = self.merge_behavior(); - - res.allow_snippets(try_or!( - self.caps - .text_document - .as_ref()? - .completion - .as_ref()? - .completion_item - .as_ref()? - .snippet_support?, - false - )); - res + CompletionConfig { + enable_postfix_completions: self.data.completion_postfix_enable, + enable_autoimport_completions: self.data.completion_autoimport_enable + && completion_item_edit_resolve(&self.caps), + add_call_parenthesis: self.data.completion_addCallParenthesis, + add_call_argument_snippets: self.data.completion_addCallArgumentSnippets, + merge: self.merge_behavior(), + snippet_cap: SnippetCap::new(try_or!( + self.caps + .text_document + .as_ref()? + .completion + .as_ref()? + .completion_item + .as_ref()? + .snippet_support?, + false + )), + } } pub fn assist(&self) -> AssistConfig { - let mut res = AssistConfig::default(); - res.insert_use.merge = self.merge_behavior(); - res.insert_use.prefix_kind = match self.data.assist_importPrefix { - ImportPrefixDef::Plain => PrefixKind::Plain, - ImportPrefixDef::ByCrate => PrefixKind::ByCrate, - ImportPrefixDef::BySelf => PrefixKind::BySelf, - }; - res.allow_snippets(self.experimental("snippetTextEdit")); - res + AssistConfig { + snippet_cap: SnippetCap::new(self.experimental("snippetTextEdit")), + allowed: None, + insert_use: InsertUseConfig { + merge: self.merge_behavior(), + prefix_kind: match self.data.assist_importPrefix { + ImportPrefixDef::Plain => PrefixKind::Plain, + ImportPrefixDef::ByCrate => PrefixKind::ByCrate, + ImportPrefixDef::BySelf => PrefixKind::BySelf, + }, + }, + } } pub fn call_info_full(&self) -> bool { self.data.callInfo_full diff --git a/crates/rust-analyzer/src/to_proto.rs b/crates/rust-analyzer/src/to_proto.rs index a5f7e3af72..bb221c1d18 100644 --- a/crates/rust-analyzer/src/to_proto.rs +++ b/crates/rust-analyzer/src/to_proto.rs @@ -850,6 +850,7 @@ pub(crate) fn markup_content(markup: Markup) -> lsp_types::MarkupContent { #[cfg(test)] mod tests { use ide::Analysis; + use ide_db::helpers::SnippetCap; use super::*; @@ -868,7 +869,14 @@ mod tests { let (analysis, file_id) = Analysis::from_single_file(text); let completions: Vec<(String, Option)> = analysis .completions( - &ide::CompletionConfig::default(), + &ide::CompletionConfig { + enable_postfix_completions: true, + enable_autoimport_completions: true, + add_call_parenthesis: true, + add_call_argument_snippets: true, + snippet_cap: SnippetCap::new(true), + merge: None, + }, ide_db::base_db::FilePosition { file_id, offset }, ) .unwrap()