Skip to content

Move FeatureFlags #3551

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Mar 10, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 23 additions & 2 deletions crates/ra_ide/src/completion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,23 @@ pub use crate::completion::completion_item::{
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.
///
/// First, we look at the position and collect a so-called `CompletionContext.
Expand All @@ -55,8 +72,12 @@ pub use crate::completion::completion_item::{
/// `foo` *should* be present among the completion variants. Filtering by
/// identifier prefix/fuzzy match should be done higher in the stack, together
/// with ordering of completions (currently this is done by the client).
pub(crate) fn completions(db: &RootDatabase, position: FilePosition) -> Option<Completions> {
let ctx = CompletionContext::new(db, position)?;
pub(crate) fn completions(
db: &RootDatabase,
position: FilePosition,
opts: &CompletionOptions,
) -> Option<Completions> {
let ctx = CompletionContext::new(db, position, opts)?;

let mut acc = Completions::default();

Expand Down
2 changes: 1 addition & 1 deletion crates/ra_ide/src/completion/complete_postfix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use crate::{
};

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;
}

Expand Down
5 changes: 4 additions & 1 deletion crates/ra_ide/src/completion/completion_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,15 @@ use ra_syntax::{
};
use ra_text_edit::AtomTextEdit;

use crate::FilePosition;
use crate::{completion::CompletionOptions, FilePosition};

/// `CompletionContext` is created early during completion to figure out, where
/// exactly is the cursor, syntax-wise.
#[derive(Debug)]
pub(crate) struct CompletionContext<'a> {
pub(super) sema: Semantics<'a, RootDatabase>,
pub(super) db: &'a RootDatabase,
pub(super) options: &'a CompletionOptions,
pub(super) offset: TextUnit,
/// The token before the cursor, in the original file.
pub(super) original_token: SyntaxToken,
Expand Down Expand Up @@ -57,6 +58,7 @@ impl<'a> CompletionContext<'a> {
pub(super) fn new(
db: &'a RootDatabase,
position: FilePosition,
options: &'a CompletionOptions,
) -> Option<CompletionContext<'a>> {
let sema = Semantics::new(db);

Expand All @@ -80,6 +82,7 @@ impl<'a> CompletionContext<'a> {
let mut ctx = CompletionContext {
sema,
db,
options,
original_token,
token,
offset: position.offset,
Expand Down
10 changes: 7 additions & 3 deletions crates/ra_ide/src/completion/completion_item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -321,14 +321,18 @@ impl Into<Vec<CompletionItem>> for Completions {

#[cfg(test)]
pub(crate) fn do_completion(code: &str, kind: CompletionKind) -> Vec<CompletionItem> {
use crate::completion::completions;
use crate::mock_analysis::{analysis_and_position, single_file_with_position};
use crate::{
completion::{completions, CompletionOptions},
mock_analysis::{analysis_and_position, single_file_with_position},
};

let (analysis, position) = if code.contains("//-") {
analysis_and_position(code)
} else {
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 mut kind_completions: Vec<CompletionItem> =
completion_items.into_iter().filter(|c| c.completion_kind == kind).collect();
Expand Down
16 changes: 3 additions & 13 deletions crates/ra_ide/src/completion/presentation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,10 +104,7 @@ impl Completions {
};

// Add `<>` for generic types
if ctx.is_path_type
&& !ctx.has_type_args
&& ctx.db.feature_flags.get("completion.insertion.add-call-parenthesis")
{
if ctx.is_path_type && !ctx.has_type_args && ctx.options.add_call_parenthesis {
let has_non_default_type_params = match resolution {
ScopeDef::ModuleDef(Adt(it)) => it.has_non_default_type_params(ctx.db),
ScopeDef::ModuleDef(TypeAlias(it)) => it.has_non_default_type_params(ctx.db),
Expand Down Expand Up @@ -212,21 +209,14 @@ impl Completions {
.detail(function_signature.to_string());

// If not an import, add parenthesis automatically.
if ctx.use_item_syntax.is_none()
&& !ctx.is_call
&& ctx.db.feature_flags.get("completion.insertion.add-call-parenthesis")
{
if ctx.use_item_syntax.is_none() && !ctx.is_call && ctx.options.add_call_parenthesis {
tested_by!(inserts_parens_for_function_calls);

let (snippet, label) = if params.is_empty() || has_self_param && params.len() == 1 {
(format!("{}()$0", name), format!("{}()", name))
} else {
builder = builder.trigger_call_info();
let snippet = if ctx
.db
.feature_flags
.get("completion.insertion.add-argument-snippets")
{
let snippet = if ctx.options.add_call_argument_snippets {
let to_skip = if has_self_param { 1 } else { 0 };
let function_params_snippet = join(
function_signature.parameter_names.iter().skip(to_skip).enumerate().map(
Expand Down
26 changes: 10 additions & 16 deletions crates/ra_ide/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ use crate::display::ToNav;
pub use crate::{
assists::{Assist, AssistId},
call_hierarchy::CallItem,
completion::{CompletionItem, CompletionItemKind, InsertTextFormat},
completion::{CompletionItem, CompletionItemKind, CompletionOptions, InsertTextFormat},
diagnostics::Severity,
display::{file_structure, FunctionSignature, NavigationTarget, StructureNode},
expand_macro::ExpandedMacro,
Expand All @@ -84,7 +84,6 @@ pub use ra_db::{
};
pub use ra_ide_db::{
change::{AnalysisChange, LibraryData},
feature_flags::FeatureFlags,
line_index::{LineCol, LineIndex},
line_index_utils::translate_offset_with_edit,
search::SearchScope,
Expand Down Expand Up @@ -131,24 +130,20 @@ pub struct AnalysisHost {

impl Default for AnalysisHost {
fn default() -> AnalysisHost {
AnalysisHost::new(None, FeatureFlags::default())
AnalysisHost::new(None)
}
}

impl AnalysisHost {
pub fn new(lru_capcity: Option<usize>, feature_flags: FeatureFlags) -> AnalysisHost {
AnalysisHost { db: RootDatabase::new(lru_capcity, feature_flags) }
pub fn new(lru_capacity: Option<usize>) -> AnalysisHost {
AnalysisHost { db: RootDatabase::new(lru_capacity) }
}
/// Returns a snapshot of the current state, which you can query for
/// semantic information.
pub fn analysis(&self) -> Analysis {
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
/// outstanding snapshots, they will be canceled.
pub fn apply_change(&mut self, change: AnalysisChange) {
Expand Down Expand Up @@ -224,11 +219,6 @@ impl Analysis {
(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.
pub fn status(&self) -> Cancelable<String> {
self.with_db(|db| status::status(&*db))
Expand Down Expand Up @@ -450,8 +440,12 @@ impl Analysis {
}

/// Computes completions at the given position.
pub fn completions(&self, position: FilePosition) -> Cancelable<Option<Vec<CompletionItem>>> {
self.with_db(|db| completion::completions(db, position).map(Into::into))
pub fn completions(
&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
Expand Down
10 changes: 3 additions & 7 deletions crates/ra_ide_db/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
pub mod marks;
pub mod line_index;
pub mod line_index_utils;
pub mod feature_flags;
pub mod symbol_index;
pub mod change;
pub mod defs;
Expand All @@ -22,7 +21,7 @@ use ra_db::{
};
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(
ra_db::SourceDatabaseStorage,
Expand All @@ -37,7 +36,6 @@ use crate::{feature_flags::FeatureFlags, line_index::LineIndex, symbol_index::Sy
#[derive(Debug)]
pub struct RootDatabase {
runtime: salsa::Runtime<RootDatabase>,
pub feature_flags: Arc<FeatureFlags>,
pub(crate) debug_data: Arc<DebugData>,
pub last_gc: crate::wasm_shims::Instant,
pub last_gc_check: crate::wasm_shims::Instant,
Expand Down Expand Up @@ -82,17 +80,16 @@ impl salsa::Database for RootDatabase {

impl Default for RootDatabase {
fn default() -> RootDatabase {
RootDatabase::new(None, FeatureFlags::default())
RootDatabase::new(None)
}
}

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 {
runtime: salsa::Runtime::default(),
last_gc: crate::wasm_shims::Instant::now(),
last_gc_check: crate::wasm_shims::Instant::now(),
feature_flags: Arc::new(feature_flags),
debug_data: Default::default(),
};
db.set_crate_graph_with_durability(Default::default(), Durability::HIGH);
Expand All @@ -112,7 +109,6 @@ impl salsa::ParallelDatabase for RootDatabase {
runtime: self.runtime.snapshot(self),
last_gc: self.last_gc,
last_gc_check: self.last_gc_check,
feature_flags: Arc::clone(&self.feature_flags),
debug_data: Arc::clone(&self.debug_data),
})
}
Expand Down
12 changes: 7 additions & 5 deletions crates/rust-analyzer/src/cli/analysis_bench.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use ra_db::{
salsa::{Database, Durability},
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};

Expand Down Expand Up @@ -94,17 +94,19 @@ pub fn analysis_bench(verbosity: Verbosity, path: &Path, what: BenchWhat) -> Res
.analysis()
.file_line_index(file_id)?
.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 {
let res =
do_work(&mut host, file_id, |analysis| analysis.completions(file_postion));
let options = CompletionOptions::default();
let res = do_work(&mut host, file_id, |analysis| {
analysis.completions(file_position, &options)
});
if verbosity.is_verbose() {
println!("\n{:#?}", res);
}
} else {
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() {
println!("\n{:#?}", res);
}
Expand Down
4 changes: 2 additions & 2 deletions crates/rust-analyzer/src/cli/load_cargo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use std::path::Path;
use anyhow::Result;
use crossbeam_channel::{unbounded, Receiver};
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_vfs::{RootEntry, Vfs, VfsChange, VfsTask, Watch};
use rustc_hash::{FxHashMap, FxHashSet};
Expand Down Expand Up @@ -82,7 +82,7 @@ pub(crate) fn load(
receiver: Receiver<VfsTask>,
) -> AnalysisHost {
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();
analysis_change.set_crate_graph(crate_graph);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

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
/// rust-analyzer.
///
Expand Down
1 change: 1 addition & 0 deletions crates/rust-analyzer/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ mod config;
mod world;
mod diagnostics;
mod semantic_tokens;
mod feature_flags;

use serde::de::DeserializeOwned;

Expand Down
7 changes: 4 additions & 3 deletions crates/rust-analyzer/src/main_loop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use crossbeam_channel::{select, unbounded, RecvError, Sender};
use lsp_server::{Connection, ErrorCode, Message, Notification, Request, RequestId, Response};
use lsp_types::{ClientCapabilities, NumberOrString};
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_vfs::{VfsFile, VfsTask, Watch};
use relative_path::RelativePathBuf;
Expand All @@ -28,6 +28,7 @@ use threadpool::ThreadPool;

use crate::{
diagnostics::DiagnosticTask,
feature_flags::FeatureFlags,
main_loop::{
pending_requests::{PendingRequest, PendingRequests},
subscriptions::Subscriptions,
Expand Down Expand Up @@ -423,7 +424,7 @@ fn loop_turn(
{
loop_state.workspace_loaded = true;
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);
show_message(req::MessageType::Info, msg, &connection.sender);
}
Expand Down Expand Up @@ -839,7 +840,7 @@ fn update_file_notifications_on_threadpool(
subscriptions: Vec<FileId>,
) {
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 || {
for file_id in subscriptions {
if publish_diagnostics {
Expand Down
Loading