6331: correct hover text for items with doc attribute with raw strings r=matklad a=JoshMcguigan Fixes #6300 by improving the handling of raw string literals in attribute style doc comments. This still has a bug where it could consume too many `"` at the start or end of the comment text, just as the original code had. Not sure if we want to fix that as part of this PR or not? If so, I think I'd prefer to add a unit test for either the `as_simple_key_value` function (I'm not exactly sure where this would belong / how to set this up) or create a `fn(&SmolStr) -> &SmolStr` to unit test by factoring out the `trim` operations from `as_simple_key_value`. Thoughts on this? 6342: Shorter dependency chain r=matklad a=popzxc Continuing implementing suggestions from the `Completion refactoring` zulip thread. This PR does the following: - Removes dependency of `completions` on `assists` by moving required functionality into `ide_db`. - Moves completely `call_info` crate into `ide_db` as it looks like it fits perfect there. - Adds a bunch of new tests and docs. - Adds the re-export of `base_db` to the `ide_db` and removes direct dependency on `base_db` from other crates. The last point is controversial, I guess, but I noticed that in places where `ide_db` is used, `base_db` is also *always* used. Thus I think the dependency on the `base_db` is implied by the fact of `ide_db` interfaces, and thus it makes sense to just provide `base_db` out of the box. Co-authored-by: Josh Mcguigan <joshmcg88@gmail.com> Co-authored-by: Igor Aleksanov <popzxc@yandex.ru>
This commit is contained in:
commit
bf84e4958e
22
Cargo.lock
generated
22
Cargo.lock
generated
@ -50,7 +50,6 @@ checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b"
|
||||
name = "assists"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"base_db",
|
||||
"either",
|
||||
"hir",
|
||||
"ide_db",
|
||||
@ -127,20 +126,6 @@ version = "1.3.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de"
|
||||
|
||||
[[package]]
|
||||
name = "call_info"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"base_db",
|
||||
"either",
|
||||
"expect-test",
|
||||
"hir",
|
||||
"ide_db",
|
||||
"stdx",
|
||||
"syntax",
|
||||
"test_utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cargo_metadata"
|
||||
version = "0.12.0"
|
||||
@ -268,9 +253,7 @@ dependencies = [
|
||||
name = "completion"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"assists",
|
||||
"base_db",
|
||||
"call_info",
|
||||
"expect-test",
|
||||
"hir",
|
||||
"ide_db",
|
||||
@ -655,8 +638,6 @@ name = "ide"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"assists",
|
||||
"base_db",
|
||||
"call_info",
|
||||
"cfg",
|
||||
"completion",
|
||||
"either",
|
||||
@ -685,6 +666,7 @@ version = "0.0.0"
|
||||
dependencies = [
|
||||
"base_db",
|
||||
"either",
|
||||
"expect-test",
|
||||
"fst",
|
||||
"hir",
|
||||
"log",
|
||||
@ -1356,7 +1338,6 @@ name = "rust-analyzer"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"base_db",
|
||||
"cfg",
|
||||
"crossbeam-channel 0.5.0",
|
||||
"env_logger",
|
||||
@ -1614,7 +1595,6 @@ dependencies = [
|
||||
name = "ssr"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"base_db",
|
||||
"expect-test",
|
||||
"hir",
|
||||
"ide_db",
|
||||
|
@ -18,7 +18,6 @@ stdx = { path = "../stdx", version = "0.0.0" }
|
||||
syntax = { path = "../syntax", version = "0.0.0" }
|
||||
text_edit = { path = "../text_edit", version = "0.0.0" }
|
||||
profile = { path = "../profile", version = "0.0.0" }
|
||||
base_db = { path = "../base_db", version = "0.0.0" }
|
||||
ide_db = { path = "../ide_db", version = "0.0.0" }
|
||||
hir = { path = "../hir", version = "0.0.0" }
|
||||
test_utils = { path = "../test_utils", version = "0.0.0" }
|
||||
|
@ -3,8 +3,8 @@
|
||||
use std::mem;
|
||||
|
||||
use algo::find_covering_element;
|
||||
use base_db::{FileId, FileRange};
|
||||
use hir::Semantics;
|
||||
use ide_db::base_db::{FileId, FileRange};
|
||||
use ide_db::{
|
||||
label::Label,
|
||||
source_change::{SourceChange, SourceFileEdit},
|
||||
|
@ -1,4 +1,5 @@
|
||||
use hir::HasSource;
|
||||
use ide_db::traits::{get_missing_assoc_items, resolve_target_trait};
|
||||
use syntax::{
|
||||
ast::{
|
||||
self,
|
||||
@ -11,7 +12,7 @@
|
||||
use crate::{
|
||||
assist_context::{AssistContext, Assists},
|
||||
ast_transform::{self, AstTransform, QualifyPaths, SubstituteTypeParams},
|
||||
utils::{get_missing_assoc_items, render_snippet, resolve_target_trait, Cursor},
|
||||
utils::{render_snippet, Cursor},
|
||||
AssistId, AssistKind,
|
||||
};
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
use base_db::FileId;
|
||||
use hir::{EnumVariant, Module, ModuleDef, Name};
|
||||
use ide_db::base_db::FileId;
|
||||
use ide_db::{defs::Definition, search::Reference, RootDatabase};
|
||||
use itertools::Itertools;
|
||||
use rustc_hash::FxHashSet;
|
||||
|
@ -1,5 +1,5 @@
|
||||
use base_db::FileId;
|
||||
use hir::{db::HirDatabase, HasSource, HasVisibility, PathResolution};
|
||||
use ide_db::base_db::FileId;
|
||||
use syntax::{
|
||||
ast::{self, VisibilityOwner},
|
||||
AstNode, TextRange, TextSize,
|
||||
|
@ -1,5 +1,5 @@
|
||||
use base_db::FileId;
|
||||
use hir::HirDisplay;
|
||||
use ide_db::base_db::FileId;
|
||||
use rustc_hash::{FxHashMap, FxHashSet};
|
||||
use syntax::{
|
||||
ast::{
|
||||
|
@ -7,10 +7,8 @@
|
||||
AstNode,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
utils::{unwrap_trivial_block, TryEnum},
|
||||
AssistContext, AssistId, AssistKind, Assists,
|
||||
};
|
||||
use crate::{utils::unwrap_trivial_block, AssistContext, AssistId, AssistKind, Assists};
|
||||
use ide_db::ty_filter::TryEnum;
|
||||
|
||||
// Assist: replace_if_let_with_match
|
||||
//
|
||||
|
@ -9,7 +9,8 @@
|
||||
AstNode, T,
|
||||
};
|
||||
|
||||
use crate::{utils::TryEnum, AssistContext, AssistId, AssistKind, Assists};
|
||||
use crate::{AssistContext, AssistId, AssistKind, Assists};
|
||||
use ide_db::ty_filter::TryEnum;
|
||||
|
||||
// Assist: replace_let_with_if_let
|
||||
//
|
||||
|
@ -10,9 +10,10 @@
|
||||
};
|
||||
|
||||
use crate::{
|
||||
utils::{render_snippet, Cursor, TryEnum},
|
||||
utils::{render_snippet, Cursor},
|
||||
AssistContext, AssistId, AssistKind, Assists,
|
||||
};
|
||||
use ide_db::ty_filter::TryEnum;
|
||||
|
||||
// Assist: replace_unwrap_with_match
|
||||
//
|
||||
|
@ -17,8 +17,8 @@ macro_rules! eprintln {
|
||||
pub mod utils;
|
||||
pub mod ast_transform;
|
||||
|
||||
use base_db::FileRange;
|
||||
use hir::Semantics;
|
||||
use ide_db::base_db::FileRange;
|
||||
use ide_db::{label::Label, source_change::SourceChange, RootDatabase};
|
||||
use syntax::TextRange;
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
mod generated;
|
||||
|
||||
use base_db::{fixture::WithFixture, FileId, FileRange, SourceDatabaseExt};
|
||||
use hir::Semantics;
|
||||
use ide_db::base_db::{fixture::WithFixture, FileId, FileRange, SourceDatabaseExt};
|
||||
use ide_db::RootDatabase;
|
||||
use syntax::TextRange;
|
||||
use test_utils::{assert_eq_text, extract_offset, extract_range};
|
||||
|
@ -2,14 +2,13 @@
|
||||
pub(crate) mod insert_use;
|
||||
pub(crate) mod import_assets;
|
||||
|
||||
use std::{iter, ops};
|
||||
use std::ops;
|
||||
|
||||
use hir::{Adt, Crate, Enum, Module, ScopeDef, Semantics, Trait, Type};
|
||||
use hir::{Crate, Enum, Module, ScopeDef, Semantics, Trait};
|
||||
use ide_db::RootDatabase;
|
||||
use itertools::Itertools;
|
||||
use rustc_hash::FxHashSet;
|
||||
use syntax::{
|
||||
ast::{self, make, ArgListOwner, NameOwner},
|
||||
ast::{self, make, ArgListOwner},
|
||||
AstNode, Direction,
|
||||
SyntaxKind::*,
|
||||
SyntaxNode, TextSize, T,
|
||||
@ -115,72 +114,6 @@ fn escape(buf: &mut String) {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_missing_assoc_items(
|
||||
sema: &Semantics<RootDatabase>,
|
||||
impl_def: &ast::Impl,
|
||||
) -> Vec<hir::AssocItem> {
|
||||
// Names must be unique between constants and functions. However, type aliases
|
||||
// may share the same name as a function or constant.
|
||||
let mut impl_fns_consts = FxHashSet::default();
|
||||
let mut impl_type = FxHashSet::default();
|
||||
|
||||
if let Some(item_list) = impl_def.assoc_item_list() {
|
||||
for item in item_list.assoc_items() {
|
||||
match item {
|
||||
ast::AssocItem::Fn(f) => {
|
||||
if let Some(n) = f.name() {
|
||||
impl_fns_consts.insert(n.syntax().to_string());
|
||||
}
|
||||
}
|
||||
|
||||
ast::AssocItem::TypeAlias(t) => {
|
||||
if let Some(n) = t.name() {
|
||||
impl_type.insert(n.syntax().to_string());
|
||||
}
|
||||
}
|
||||
|
||||
ast::AssocItem::Const(c) => {
|
||||
if let Some(n) = c.name() {
|
||||
impl_fns_consts.insert(n.syntax().to_string());
|
||||
}
|
||||
}
|
||||
ast::AssocItem::MacroCall(_) => (),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
resolve_target_trait(sema, impl_def).map_or(vec![], |target_trait| {
|
||||
target_trait
|
||||
.items(sema.db)
|
||||
.iter()
|
||||
.filter(|i| match i {
|
||||
hir::AssocItem::Function(f) => {
|
||||
!impl_fns_consts.contains(&f.name(sema.db).to_string())
|
||||
}
|
||||
hir::AssocItem::TypeAlias(t) => !impl_type.contains(&t.name(sema.db).to_string()),
|
||||
hir::AssocItem::Const(c) => c
|
||||
.name(sema.db)
|
||||
.map(|n| !impl_fns_consts.contains(&n.to_string()))
|
||||
.unwrap_or_default(),
|
||||
})
|
||||
.cloned()
|
||||
.collect()
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn resolve_target_trait(
|
||||
sema: &Semantics<RootDatabase>,
|
||||
impl_def: &ast::Impl,
|
||||
) -> Option<hir::Trait> {
|
||||
let ast_path =
|
||||
impl_def.trait_().map(|it| it.syntax().clone()).and_then(ast::PathType::cast)?.path()?;
|
||||
|
||||
match sema.resolve_path(&ast_path) {
|
||||
Some(hir::PathResolution::Def(hir::ModuleDef::Trait(def))) => Some(def),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn vis_offset(node: &SyntaxNode) -> TextSize {
|
||||
node.children_with_tokens()
|
||||
.find(|it| !matches!(it.kind(), WHITESPACE | COMMENT | ATTR))
|
||||
@ -223,54 +156,6 @@ fn invert_special_case(expr: &ast::Expr) -> Option<ast::Expr> {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub enum TryEnum {
|
||||
Result,
|
||||
Option,
|
||||
}
|
||||
|
||||
impl TryEnum {
|
||||
const ALL: [TryEnum; 2] = [TryEnum::Option, TryEnum::Result];
|
||||
|
||||
pub fn from_ty(sema: &Semantics<RootDatabase>, ty: &Type) -> Option<TryEnum> {
|
||||
let enum_ = match ty.as_adt() {
|
||||
Some(Adt::Enum(it)) => it,
|
||||
_ => return None,
|
||||
};
|
||||
TryEnum::ALL.iter().find_map(|&var| {
|
||||
if &enum_.name(sema.db).to_string() == var.type_name() {
|
||||
return Some(var);
|
||||
}
|
||||
None
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn happy_case(self) -> &'static str {
|
||||
match self {
|
||||
TryEnum::Result => "Ok",
|
||||
TryEnum::Option => "Some",
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn sad_pattern(self) -> ast::Pat {
|
||||
match self {
|
||||
TryEnum::Result => make::tuple_struct_pat(
|
||||
make::path_unqualified(make::path_segment(make::name_ref("Err"))),
|
||||
iter::once(make::wildcard_pat().into()),
|
||||
)
|
||||
.into(),
|
||||
TryEnum::Option => make::ident_pat(make::name("None")).into(),
|
||||
}
|
||||
}
|
||||
|
||||
fn type_name(self) -> &'static str {
|
||||
match self {
|
||||
TryEnum::Result => "Result",
|
||||
TryEnum::Option => "Option",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Helps with finding well-know things inside the standard library. This is
|
||||
/// somewhat similar to the known paths infra inside hir, but it different; We
|
||||
/// want to make sure that IDE specific paths don't become interesting inside
|
||||
|
@ -1,26 +0,0 @@
|
||||
[package]
|
||||
name = "call_info"
|
||||
version = "0.0.0"
|
||||
description = "TBD"
|
||||
license = "MIT OR Apache-2.0"
|
||||
authors = ["rust-analyzer developers"]
|
||||
edition = "2018"
|
||||
|
||||
[lib]
|
||||
doctest = false
|
||||
|
||||
[dependencies]
|
||||
either = "1.5.3"
|
||||
|
||||
stdx = { path = "../stdx", version = "0.0.0" }
|
||||
syntax = { path = "../syntax", version = "0.0.0" }
|
||||
base_db = { path = "../base_db", version = "0.0.0" }
|
||||
ide_db = { path = "../ide_db", version = "0.0.0" }
|
||||
test_utils = { path = "../test_utils", version = "0.0.0" }
|
||||
|
||||
# call_info crate should depend only on the top-level `hir` package. if you need
|
||||
# something from some `hir_xxx` subpackage, reexport the API via `hir`.
|
||||
hir = { path = "../hir", version = "0.0.0" }
|
||||
|
||||
[dev-dependencies]
|
||||
expect-test = "1.0"
|
@ -21,8 +21,6 @@ base_db = { path = "../base_db", version = "0.0.0" }
|
||||
ide_db = { path = "../ide_db", version = "0.0.0" }
|
||||
profile = { path = "../profile", version = "0.0.0" }
|
||||
test_utils = { path = "../test_utils", version = "0.0.0" }
|
||||
assists = { path = "../assists", version = "0.0.0" }
|
||||
call_info = { path = "../call_info", version = "0.0.0" }
|
||||
|
||||
# completions crate should depend only on the top-level `hir` package. if you need
|
||||
# something from some `hir_xxx` subpackage, reexport the API via `hir`.
|
||||
|
@ -1,7 +1,7 @@
|
||||
//! Completes mod declarations.
|
||||
|
||||
use base_db::{SourceDatabaseExt, VfsPath};
|
||||
use hir::{Module, ModuleSource};
|
||||
use ide_db::base_db::{SourceDatabaseExt, VfsPath};
|
||||
use ide_db::RootDatabase;
|
||||
use rustc_hash::FxHashSet;
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
mod format_like;
|
||||
|
||||
use assists::utils::TryEnum;
|
||||
use ide_db::ty_filter::TryEnum;
|
||||
use syntax::{
|
||||
ast::{self, AstNode, AstToken},
|
||||
TextRange, TextSize,
|
||||
|
@ -31,8 +31,8 @@
|
||||
//! }
|
||||
//! ```
|
||||
|
||||
use assists::utils::get_missing_assoc_items;
|
||||
use hir::{self, HasAttrs, HasSource};
|
||||
use ide_db::traits::get_missing_assoc_items;
|
||||
use syntax::{
|
||||
ast::{self, edit, Impl},
|
||||
display::function_declaration,
|
||||
|
@ -1,9 +1,8 @@
|
||||
//! See `CompletionContext` structure.
|
||||
|
||||
use base_db::{FilePosition, SourceDatabase};
|
||||
use call_info::ActiveParameter;
|
||||
use hir::{Local, ScopeDef, Semantics, SemanticsScope, Type};
|
||||
use ide_db::RootDatabase;
|
||||
use ide_db::base_db::{FilePosition, SourceDatabase};
|
||||
use ide_db::{call_info::ActiveParameter, RootDatabase};
|
||||
use syntax::{
|
||||
algo::{find_covering_element, find_node_at_offset},
|
||||
ast, match_ast, AstNode, NodeOrToken,
|
||||
|
@ -23,7 +23,7 @@
|
||||
mod complete_trait_impl;
|
||||
mod complete_mod;
|
||||
|
||||
use base_db::FilePosition;
|
||||
use ide_db::base_db::FilePosition;
|
||||
use ide_db::RootDatabase;
|
||||
|
||||
use crate::{
|
||||
|
@ -1,7 +1,7 @@
|
||||
//! Runs completion for testing purposes.
|
||||
|
||||
use base_db::{fixture::ChangeFixture, FileLoader, FilePosition};
|
||||
use hir::Semantics;
|
||||
use ide_db::base_db::{fixture::ChangeFixture, FileLoader, FilePosition};
|
||||
use ide_db::RootDatabase;
|
||||
use itertools::Itertools;
|
||||
use stdx::{format_to, trim_indent};
|
||||
|
@ -23,14 +23,12 @@ url = "2.1.1"
|
||||
stdx = { path = "../stdx", version = "0.0.0" }
|
||||
syntax = { path = "../syntax", version = "0.0.0" }
|
||||
text_edit = { path = "../text_edit", version = "0.0.0" }
|
||||
base_db = { path = "../base_db", version = "0.0.0" }
|
||||
ide_db = { path = "../ide_db", version = "0.0.0" }
|
||||
cfg = { path = "../cfg", version = "0.0.0" }
|
||||
profile = { path = "../profile", version = "0.0.0" }
|
||||
test_utils = { path = "../test_utils", version = "0.0.0" }
|
||||
assists = { path = "../assists", version = "0.0.0" }
|
||||
ssr = { path = "../ssr", version = "0.0.0" }
|
||||
call_info = { path = "../call_info", version = "0.0.0" }
|
||||
completion = { path = "../completion", version = "0.0.0" }
|
||||
|
||||
# ide should depend only on the top-level `hir` package. if you need
|
||||
|
@ -2,8 +2,8 @@
|
||||
|
||||
use indexmap::IndexMap;
|
||||
|
||||
use call_info::FnCallNode;
|
||||
use hir::Semantics;
|
||||
use ide_db::call_info::FnCallNode;
|
||||
use ide_db::RootDatabase;
|
||||
use syntax::{ast, match_ast, AstNode, TextRange};
|
||||
|
||||
@ -137,7 +137,7 @@ fn into_items(self) -> Vec<CallItem> {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use base_db::FilePosition;
|
||||
use ide_db::base_db::FilePosition;
|
||||
|
||||
use crate::fixture;
|
||||
|
||||
|
@ -9,11 +9,11 @@
|
||||
|
||||
use std::cell::RefCell;
|
||||
|
||||
use base_db::SourceDatabase;
|
||||
use hir::{
|
||||
diagnostics::{Diagnostic as _, DiagnosticSinkBuilder},
|
||||
Semantics,
|
||||
};
|
||||
use ide_db::base_db::SourceDatabase;
|
||||
use ide_db::RootDatabase;
|
||||
use itertools::Itertools;
|
||||
use rustc_hash::FxHashSet;
|
||||
|
@ -1,7 +1,7 @@
|
||||
//! Suggests shortening `Foo { field: field }` to `Foo { field }` in both
|
||||
//! expressions and patterns.
|
||||
|
||||
use base_db::FileId;
|
||||
use ide_db::base_db::FileId;
|
||||
use ide_db::source_change::SourceFileEdit;
|
||||
use syntax::{ast, match_ast, AstNode, SyntaxNode};
|
||||
use text_edit::TextEdit;
|
||||
|
@ -1,6 +1,5 @@
|
||||
//! Provides a way to attach fixes to the diagnostics.
|
||||
//! The same module also has all curret custom fixes for the diagnostics implemented.
|
||||
use base_db::FileId;
|
||||
use hir::{
|
||||
db::AstDatabase,
|
||||
diagnostics::{
|
||||
@ -9,6 +8,7 @@
|
||||
},
|
||||
HasSource, HirDisplay, Semantics, VariantDef,
|
||||
};
|
||||
use ide_db::base_db::FileId;
|
||||
use ide_db::{
|
||||
source_change::{FileSystemEdit, SourceFileEdit},
|
||||
RootDatabase,
|
||||
|
@ -1,8 +1,8 @@
|
||||
//! FIXME: write short doc here
|
||||
|
||||
use base_db::{FileId, SourceDatabase};
|
||||
use either::Either;
|
||||
use hir::{original_range, AssocItem, FieldSource, HasSource, InFile, ModuleSource};
|
||||
use ide_db::base_db::{FileId, SourceDatabase};
|
||||
use ide_db::{defs::Definition, RootDatabase};
|
||||
use syntax::{
|
||||
ast::{self, DocCommentsOwner, NameOwner},
|
||||
|
@ -1,5 +1,5 @@
|
||||
//! Utilities for creating `Analysis` instances for tests.
|
||||
use base_db::fixture::ChangeFixture;
|
||||
use ide_db::base_db::fixture::ChangeFixture;
|
||||
use test_utils::{extract_annotations, RangeOrOffset};
|
||||
|
||||
use crate::{Analysis, AnalysisHost, FileId, FilePosition, FileRange};
|
||||
|
@ -100,7 +100,7 @@ pub(crate) fn reference_definition(
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use base_db::FileRange;
|
||||
use ide_db::base_db::FileRange;
|
||||
use syntax::{TextRange, TextSize};
|
||||
|
||||
use crate::fixture;
|
||||
|
@ -74,7 +74,7 @@ fn impls_for_trait(
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use base_db::FileRange;
|
||||
use ide_db::base_db::FileRange;
|
||||
|
||||
use crate::fixture;
|
||||
|
||||
|
@ -54,7 +54,7 @@ fn priority(n: &SyntaxToken) -> usize {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use base_db::FileRange;
|
||||
use ide_db::base_db::FileRange;
|
||||
|
||||
use crate::fixture;
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
use base_db::SourceDatabase;
|
||||
use hir::{
|
||||
Adt, AsAssocItem, AssocItemContainer, Documentation, FieldSource, HasSource, HirDisplay,
|
||||
Module, ModuleDef, ModuleSource, Semantics,
|
||||
};
|
||||
use ide_db::base_db::SourceDatabase;
|
||||
use ide_db::{
|
||||
defs::{Definition, NameClass, NameRefClass},
|
||||
RootDatabase,
|
||||
@ -385,8 +385,8 @@ fn priority(n: &SyntaxToken) -> usize {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use base_db::FileLoader;
|
||||
use expect_test::{expect, Expect};
|
||||
use ide_db::base_db::FileLoader;
|
||||
|
||||
use crate::fixture;
|
||||
|
||||
@ -637,6 +637,33 @@ pub fn foo(_: &Path)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn hover_shows_fn_doc_attr_raw_string() {
|
||||
check(
|
||||
r##"
|
||||
#[doc = r#"Raw string doc attr"#]
|
||||
pub fn foo<|>(_: &Path) {}
|
||||
|
||||
fn main() { }
|
||||
"##,
|
||||
expect![[r##"
|
||||
*foo*
|
||||
|
||||
```rust
|
||||
test
|
||||
```
|
||||
|
||||
```rust
|
||||
pub fn foo(_: &Path)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
Raw string doc attr
|
||||
"##]],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn hover_shows_struct_field_info() {
|
||||
// Hovering over the field when instantiating
|
||||
|
@ -48,11 +48,11 @@ macro_rules! eprintln {
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
use base_db::{
|
||||
use cfg::CfgOptions;
|
||||
use ide_db::base_db::{
|
||||
salsa::{self, ParallelDatabase},
|
||||
CheckCanceled, Env, FileLoader, FileSet, SourceDatabase, VfsPath,
|
||||
};
|
||||
use cfg::CfgOptions;
|
||||
use ide_db::{
|
||||
symbol_index::{self, FileSymbol},
|
||||
LineIndexDatabase,
|
||||
@ -80,19 +80,19 @@ macro_rules! eprintln {
|
||||
Highlight, HighlightModifier, HighlightModifiers, HighlightTag, HighlightedRange,
|
||||
},
|
||||
};
|
||||
pub use call_info::CallInfo;
|
||||
pub use completion::{
|
||||
CompletionConfig, CompletionItem, CompletionItemKind, CompletionScore, InsertTextFormat,
|
||||
};
|
||||
pub use ide_db::call_info::CallInfo;
|
||||
|
||||
pub use assists::{
|
||||
utils::MergeBehaviour, Assist, AssistConfig, AssistId, AssistKind, ResolvedAssist,
|
||||
};
|
||||
pub use base_db::{
|
||||
pub use hir::{Documentation, Semantics};
|
||||
pub use ide_db::base_db::{
|
||||
Canceled, Change, CrateGraph, CrateId, Edition, FileId, FilePosition, FileRange, SourceRoot,
|
||||
SourceRootId,
|
||||
};
|
||||
pub use hir::{Documentation, Semantics};
|
||||
pub use ide_db::{
|
||||
label::Label,
|
||||
line_index::{LineCol, LineIndex},
|
||||
@ -396,7 +396,7 @@ pub fn external_docs(
|
||||
|
||||
/// Computes parameter information for the given call expression.
|
||||
pub fn call_info(&self, position: FilePosition) -> Cancelable<Option<CallInfo>> {
|
||||
self.with_db(|db| call_info::call_info(db, position))
|
||||
self.with_db(|db| ide_db::call_info::call_info(db, position))
|
||||
}
|
||||
|
||||
/// Computes call hierarchy candidates for the given file position.
|
||||
|
@ -1,5 +1,5 @@
|
||||
use base_db::{CrateId, FileId, FilePosition};
|
||||
use hir::Semantics;
|
||||
use ide_db::base_db::{CrateId, FileId, FilePosition};
|
||||
use ide_db::RootDatabase;
|
||||
use syntax::{
|
||||
algo::find_node_at_offset,
|
||||
|
@ -3,8 +3,8 @@
|
||||
//! request takes longer to compute. This modules implemented prepopulating of
|
||||
//! various caches, it's not really advanced at the moment.
|
||||
|
||||
use base_db::SourceDatabase;
|
||||
use hir::db::DefDatabase;
|
||||
use ide_db::base_db::SourceDatabase;
|
||||
|
||||
use crate::RootDatabase;
|
||||
|
||||
|
@ -191,8 +191,8 @@ fn get_struct_def_name_for_struct_literal_search(
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use base_db::FileId;
|
||||
use expect_test::{expect, Expect};
|
||||
use ide_db::base_db::FileId;
|
||||
use stdx::format_to;
|
||||
|
||||
use crate::{fixture, SearchScope};
|
||||
|
@ -1,7 +1,7 @@
|
||||
//! FIXME: write short doc here
|
||||
|
||||
use base_db::SourceDatabaseExt;
|
||||
use hir::{Module, ModuleDef, ModuleSource, Semantics};
|
||||
use ide_db::base_db::SourceDatabaseExt;
|
||||
use ide_db::{
|
||||
defs::{Definition, NameClass, NameRefClass},
|
||||
RootDatabase,
|
||||
|
@ -1,10 +1,10 @@
|
||||
use std::{fmt, iter::FromIterator, sync::Arc};
|
||||
|
||||
use base_db::{
|
||||
use hir::MacroFile;
|
||||
use ide_db::base_db::{
|
||||
salsa::debug::{DebugQueryTable, TableEntry},
|
||||
CrateId, FileId, FileTextQuery, SourceDatabase, SourceRootId,
|
||||
};
|
||||
use hir::MacroFile;
|
||||
use ide_db::{
|
||||
symbol_index::{LibrarySymbolsQuery, SymbolIndex},
|
||||
RootDatabase,
|
||||
@ -16,7 +16,7 @@
|
||||
use syntax::{ast, Parse, SyntaxNode};
|
||||
|
||||
fn syntax_tree_stats(db: &RootDatabase) -> SyntaxTreeStats {
|
||||
base_db::ParseQuery.in_db(db).entries::<SyntaxTreeStats>()
|
||||
ide_db::base_db::ParseQuery.in_db(db).entries::<SyntaxTreeStats>()
|
||||
}
|
||||
fn macro_syntax_tree_stats(db: &RootDatabase) -> SyntaxTreeStats {
|
||||
hir::db::ParseMacroQuery.in_db(db).entries::<SyntaxTreeStats>()
|
||||
|
@ -1,6 +1,6 @@
|
||||
//! Renders a bit of code as HTML.
|
||||
|
||||
use base_db::SourceDatabase;
|
||||
use ide_db::base_db::SourceDatabase;
|
||||
use oorandom::Rand32;
|
||||
use stdx::format_to;
|
||||
use syntax::{AstNode, TextRange, TextSize};
|
||||
|
@ -3,8 +3,8 @@
|
||||
use std::{collections::BTreeMap, convert::TryFrom};
|
||||
|
||||
use ast::{HasQuotes, HasStringValue};
|
||||
use call_info::ActiveParameter;
|
||||
use hir::Semantics;
|
||||
use ide_db::call_info::ActiveParameter;
|
||||
use itertools::Itertools;
|
||||
use syntax::{ast, AstToken, SyntaxNode, SyntaxToken, TextRange, TextSize};
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
use base_db::{FileId, SourceDatabase};
|
||||
use ide_db::base_db::{FileId, SourceDatabase};
|
||||
use ide_db::RootDatabase;
|
||||
use syntax::{
|
||||
algo, AstNode, NodeOrToken, SourceFile,
|
||||
|
@ -15,7 +15,7 @@
|
||||
|
||||
mod on_enter;
|
||||
|
||||
use base_db::{FilePosition, SourceDatabase};
|
||||
use ide_db::base_db::{FilePosition, SourceDatabase};
|
||||
use ide_db::{source_change::SourceFileEdit, RootDatabase};
|
||||
use syntax::{
|
||||
algo::find_node_at_offset,
|
||||
|
@ -1,7 +1,7 @@
|
||||
//! Handles the `Enter` key press. At the momently, this only continues
|
||||
//! comments, but should handle indent some time in the future as well.
|
||||
|
||||
use base_db::{FilePosition, SourceDatabase};
|
||||
use ide_db::base_db::{FilePosition, SourceDatabase};
|
||||
use ide_db::RootDatabase;
|
||||
use syntax::{
|
||||
ast::{self, AstToken},
|
||||
|
@ -29,3 +29,6 @@ test_utils = { path = "../test_utils", version = "0.0.0" }
|
||||
# ide should depend only on the top-level `hir` package. if you need
|
||||
# something from some `hir_xxx` subpackage, reexport the API via `hir`.
|
||||
hir = { path = "../hir", version = "0.0.0" }
|
||||
|
||||
[dev-dependencies]
|
||||
expect-test = "1.0"
|
||||
|
@ -2,7 +2,6 @@
|
||||
use base_db::FilePosition;
|
||||
use either::Either;
|
||||
use hir::{HasAttrs, HirDisplay, Semantics, Type};
|
||||
use ide_db::RootDatabase;
|
||||
use stdx::format_to;
|
||||
use syntax::{
|
||||
ast::{self, ArgListOwner},
|
||||
@ -10,6 +9,8 @@
|
||||
};
|
||||
use test_utils::mark;
|
||||
|
||||
use crate::RootDatabase;
|
||||
|
||||
/// Contains information about a call site. Specifically the
|
||||
/// `FunctionSignature`and current parameter.
|
||||
#[derive(Debug)]
|
||||
@ -228,9 +229,9 @@ fn arg_list(&self) -> Option<ast::ArgList> {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::RootDatabase;
|
||||
use base_db::{fixture::ChangeFixture, FilePosition};
|
||||
use expect_test::{expect, Expect};
|
||||
use ide_db::RootDatabase;
|
||||
use test_utils::{mark, RangeOrOffset};
|
||||
|
||||
/// Creates analysis from a multi-file fixture, returns positions marked with <|>.
|
||||
@ -249,7 +250,7 @@ pub(crate) fn position(ra_fixture: &str) -> (RootDatabase, FilePosition) {
|
||||
|
||||
fn check(ra_fixture: &str, expect: Expect) {
|
||||
let (db, position) = position(ra_fixture);
|
||||
let call_info = crate::call_info(&db, position);
|
||||
let call_info = crate::call_info::call_info(&db, position);
|
||||
let actual = match call_info {
|
||||
Some(call_info) => {
|
||||
let docs = match &call_info.doc {
|
@ -10,6 +10,9 @@
|
||||
pub mod search;
|
||||
pub mod imports_locator;
|
||||
pub mod source_change;
|
||||
pub mod ty_filter;
|
||||
pub mod traits;
|
||||
pub mod call_info;
|
||||
|
||||
use std::{fmt, sync::Arc};
|
||||
|
||||
@ -23,6 +26,9 @@
|
||||
|
||||
use crate::{line_index::LineIndex, symbol_index::SymbolsDatabase};
|
||||
|
||||
/// `base_db` is normally also needed in places where `ide_db` is used, so this re-export is for convenience.
|
||||
pub use base_db;
|
||||
|
||||
#[salsa::database(
|
||||
base_db::SourceDatabaseStorage,
|
||||
base_db::SourceDatabaseExtStorage,
|
||||
|
227
crates/ide_db/src/traits.rs
Normal file
227
crates/ide_db/src/traits.rs
Normal file
@ -0,0 +1,227 @@
|
||||
//! Functionality for obtaining data related to traits from the DB.
|
||||
|
||||
use crate::RootDatabase;
|
||||
use hir::Semantics;
|
||||
use rustc_hash::FxHashSet;
|
||||
use syntax::{
|
||||
ast::{self, NameOwner},
|
||||
AstNode,
|
||||
};
|
||||
|
||||
/// Given the `impl` block, attempts to find the trait this `impl` corresponds to.
|
||||
pub fn resolve_target_trait(
|
||||
sema: &Semantics<RootDatabase>,
|
||||
impl_def: &ast::Impl,
|
||||
) -> Option<hir::Trait> {
|
||||
let ast_path =
|
||||
impl_def.trait_().map(|it| it.syntax().clone()).and_then(ast::PathType::cast)?.path()?;
|
||||
|
||||
match sema.resolve_path(&ast_path) {
|
||||
Some(hir::PathResolution::Def(hir::ModuleDef::Trait(def))) => Some(def),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Given the `impl` block, returns the list of associated items (e.g. functions or types) that are
|
||||
/// missing in this `impl` block.
|
||||
pub fn get_missing_assoc_items(
|
||||
sema: &Semantics<RootDatabase>,
|
||||
impl_def: &ast::Impl,
|
||||
) -> Vec<hir::AssocItem> {
|
||||
// Names must be unique between constants and functions. However, type aliases
|
||||
// may share the same name as a function or constant.
|
||||
let mut impl_fns_consts = FxHashSet::default();
|
||||
let mut impl_type = FxHashSet::default();
|
||||
|
||||
if let Some(item_list) = impl_def.assoc_item_list() {
|
||||
for item in item_list.assoc_items() {
|
||||
match item {
|
||||
ast::AssocItem::Fn(f) => {
|
||||
if let Some(n) = f.name() {
|
||||
impl_fns_consts.insert(n.syntax().to_string());
|
||||
}
|
||||
}
|
||||
|
||||
ast::AssocItem::TypeAlias(t) => {
|
||||
if let Some(n) = t.name() {
|
||||
impl_type.insert(n.syntax().to_string());
|
||||
}
|
||||
}
|
||||
|
||||
ast::AssocItem::Const(c) => {
|
||||
if let Some(n) = c.name() {
|
||||
impl_fns_consts.insert(n.syntax().to_string());
|
||||
}
|
||||
}
|
||||
ast::AssocItem::MacroCall(_) => (),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
resolve_target_trait(sema, impl_def).map_or(vec![], |target_trait| {
|
||||
target_trait
|
||||
.items(sema.db)
|
||||
.iter()
|
||||
.filter(|i| match i {
|
||||
hir::AssocItem::Function(f) => {
|
||||
!impl_fns_consts.contains(&f.name(sema.db).to_string())
|
||||
}
|
||||
hir::AssocItem::TypeAlias(t) => !impl_type.contains(&t.name(sema.db).to_string()),
|
||||
hir::AssocItem::Const(c) => c
|
||||
.name(sema.db)
|
||||
.map(|n| !impl_fns_consts.contains(&n.to_string()))
|
||||
.unwrap_or_default(),
|
||||
})
|
||||
.cloned()
|
||||
.collect()
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::RootDatabase;
|
||||
use base_db::{fixture::ChangeFixture, FilePosition};
|
||||
use expect_test::{expect, Expect};
|
||||
use hir::Semantics;
|
||||
use syntax::ast::{self, AstNode};
|
||||
use test_utils::RangeOrOffset;
|
||||
|
||||
/// 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);
|
||||
let mut database = RootDatabase::default();
|
||||
database.apply_change(change_fixture.change);
|
||||
let (file_id, range_or_offset) =
|
||||
change_fixture.file_position.expect("expected a marker (<|>)");
|
||||
let offset = match range_or_offset {
|
||||
RangeOrOffset::Range(_) => panic!(),
|
||||
RangeOrOffset::Offset(it) => it,
|
||||
};
|
||||
(database, FilePosition { file_id, offset })
|
||||
}
|
||||
|
||||
fn check_trait(ra_fixture: &str, expect: Expect) {
|
||||
let (db, position) = position(ra_fixture);
|
||||
let sema = Semantics::new(&db);
|
||||
let file = sema.parse(position.file_id);
|
||||
let impl_block: ast::Impl =
|
||||
sema.find_node_at_offset_with_descend(file.syntax(), position.offset).unwrap();
|
||||
let trait_ = crate::traits::resolve_target_trait(&sema, &impl_block);
|
||||
let actual = match trait_ {
|
||||
Some(trait_) => trait_.name(&db).to_string(),
|
||||
None => String::new(),
|
||||
};
|
||||
expect.assert_eq(&actual);
|
||||
}
|
||||
|
||||
fn check_missing_assoc(ra_fixture: &str, expect: Expect) {
|
||||
let (db, position) = position(ra_fixture);
|
||||
let sema = Semantics::new(&db);
|
||||
let file = sema.parse(position.file_id);
|
||||
let impl_block: ast::Impl =
|
||||
sema.find_node_at_offset_with_descend(file.syntax(), position.offset).unwrap();
|
||||
let items = crate::traits::get_missing_assoc_items(&sema, &impl_block);
|
||||
let actual = items
|
||||
.into_iter()
|
||||
.map(|item| item.name(&db).unwrap().to_string())
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n");
|
||||
expect.assert_eq(&actual);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn resolve_trait() {
|
||||
check_trait(
|
||||
r#"
|
||||
pub trait Foo {
|
||||
fn bar();
|
||||
}
|
||||
impl Foo for u8 {
|
||||
<|>
|
||||
}
|
||||
"#,
|
||||
expect![["Foo"]],
|
||||
);
|
||||
check_trait(
|
||||
r#"
|
||||
pub trait Foo {
|
||||
fn bar();
|
||||
}
|
||||
impl Foo for u8 {
|
||||
fn bar() {
|
||||
fn baz() {
|
||||
<|>
|
||||
}
|
||||
baz();
|
||||
}
|
||||
}
|
||||
"#,
|
||||
expect![["Foo"]],
|
||||
);
|
||||
check_trait(
|
||||
r#"
|
||||
pub trait Foo {
|
||||
fn bar();
|
||||
}
|
||||
pub struct Bar;
|
||||
impl Bar {
|
||||
<|>
|
||||
}
|
||||
"#,
|
||||
expect![[""]],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn missing_assoc_items() {
|
||||
check_missing_assoc(
|
||||
r#"
|
||||
pub trait Foo {
|
||||
const FOO: u8;
|
||||
fn bar();
|
||||
}
|
||||
impl Foo for u8 {
|
||||
<|>
|
||||
}"#,
|
||||
expect![[r#"
|
||||
FOO
|
||||
bar"#]],
|
||||
);
|
||||
|
||||
check_missing_assoc(
|
||||
r#"
|
||||
pub trait Foo {
|
||||
const FOO: u8;
|
||||
fn bar();
|
||||
}
|
||||
impl Foo for u8 {
|
||||
const FOO: u8 = 10;
|
||||
<|>
|
||||
}"#,
|
||||
expect![[r#"
|
||||
bar"#]],
|
||||
);
|
||||
|
||||
check_missing_assoc(
|
||||
r#"
|
||||
pub trait Foo {
|
||||
const FOO: u8;
|
||||
fn bar();
|
||||
}
|
||||
impl Foo for u8 {
|
||||
const FOO: u8 = 10;
|
||||
fn bar() {<|>}
|
||||
}"#,
|
||||
expect![[r#""#]],
|
||||
);
|
||||
|
||||
check_missing_assoc(
|
||||
r#"
|
||||
pub struct Foo;
|
||||
impl Foo {
|
||||
fn bar() {<|>}
|
||||
}"#,
|
||||
expect![[r#""#]],
|
||||
);
|
||||
}
|
||||
}
|
58
crates/ide_db/src/ty_filter.rs
Normal file
58
crates/ide_db/src/ty_filter.rs
Normal file
@ -0,0 +1,58 @@
|
||||
//! This module contains structures for filtering the expected types.
|
||||
//! Use case for structures in this module is, for example, situation when you need to process
|
||||
//! only certain `Enum`s.
|
||||
|
||||
use crate::RootDatabase;
|
||||
use hir::{Adt, Semantics, Type};
|
||||
use std::iter;
|
||||
use syntax::ast::{self, make};
|
||||
|
||||
/// Enum types that implement `std::ops::Try` trait.
|
||||
#[derive(Clone, Copy)]
|
||||
pub enum TryEnum {
|
||||
Result,
|
||||
Option,
|
||||
}
|
||||
|
||||
impl TryEnum {
|
||||
const ALL: [TryEnum; 2] = [TryEnum::Option, TryEnum::Result];
|
||||
|
||||
/// Returns `Some(..)` if the provided type is an enum that implements `std::ops::Try`.
|
||||
pub fn from_ty(sema: &Semantics<RootDatabase>, ty: &Type) -> Option<TryEnum> {
|
||||
let enum_ = match ty.as_adt() {
|
||||
Some(Adt::Enum(it)) => it,
|
||||
_ => return None,
|
||||
};
|
||||
TryEnum::ALL.iter().find_map(|&var| {
|
||||
if &enum_.name(sema.db).to_string() == var.type_name() {
|
||||
return Some(var);
|
||||
}
|
||||
None
|
||||
})
|
||||
}
|
||||
|
||||
pub fn happy_case(self) -> &'static str {
|
||||
match self {
|
||||
TryEnum::Result => "Ok",
|
||||
TryEnum::Option => "Some",
|
||||
}
|
||||
}
|
||||
|
||||
pub fn sad_pattern(self) -> ast::Pat {
|
||||
match self {
|
||||
TryEnum::Result => make::tuple_struct_pat(
|
||||
make::path_unqualified(make::path_segment(make::name_ref("Err"))),
|
||||
iter::once(make::wildcard_pat().into()),
|
||||
)
|
||||
.into(),
|
||||
TryEnum::Option => make::ident_pat(make::name("None")).into(),
|
||||
}
|
||||
}
|
||||
|
||||
fn type_name(self) -> &'static str {
|
||||
match self {
|
||||
TryEnum::Result => "Result",
|
||||
TryEnum::Option => "Option",
|
||||
}
|
||||
}
|
||||
}
|
@ -46,7 +46,6 @@ cfg = { path = "../cfg", version = "0.0.0" }
|
||||
toolchain = { path = "../toolchain", version = "0.0.0" }
|
||||
|
||||
# This should only be used in CLI
|
||||
base_db = { path = "../base_db", version = "0.0.0" }
|
||||
ide_db = { path = "../ide_db", version = "0.0.0" }
|
||||
ssr = { path = "../ssr", version = "0.0.0" }
|
||||
hir = { path = "../hir", version = "0.0.0" }
|
||||
|
@ -3,13 +3,13 @@
|
||||
use std::{env, path::PathBuf, str::FromStr, sync::Arc, time::Instant};
|
||||
|
||||
use anyhow::{bail, format_err, Result};
|
||||
use base_db::{
|
||||
salsa::{Database, Durability},
|
||||
FileId,
|
||||
};
|
||||
use ide::{
|
||||
Analysis, AnalysisHost, Change, CompletionConfig, DiagnosticsConfig, FilePosition, LineCol,
|
||||
};
|
||||
use ide_db::base_db::{
|
||||
salsa::{Database, Durability},
|
||||
FileId,
|
||||
};
|
||||
use vfs::AbsPathBuf;
|
||||
|
||||
use crate::{
|
||||
|
@ -6,16 +6,16 @@
|
||||
time::{SystemTime, UNIX_EPOCH},
|
||||
};
|
||||
|
||||
use base_db::{
|
||||
salsa::{self, ParallelDatabase},
|
||||
SourceDatabaseExt,
|
||||
};
|
||||
use hir::{
|
||||
db::{AstDatabase, DefDatabase, HirDatabase},
|
||||
original_range, AssocItem, Crate, HasSource, HirDisplay, ModuleDef,
|
||||
};
|
||||
use hir_def::FunctionId;
|
||||
use hir_ty::{Ty, TypeWalk};
|
||||
use ide_db::base_db::{
|
||||
salsa::{self, ParallelDatabase},
|
||||
SourceDatabaseExt,
|
||||
};
|
||||
use itertools::Itertools;
|
||||
use oorandom::Rand32;
|
||||
use rayon::prelude::*;
|
||||
|
@ -6,9 +6,9 @@
|
||||
use anyhow::anyhow;
|
||||
use rustc_hash::FxHashSet;
|
||||
|
||||
use base_db::SourceDatabaseExt;
|
||||
use hir::Crate;
|
||||
use ide::{DiagnosticsConfig, Severity};
|
||||
use ide_db::base_db::SourceDatabaseExt;
|
||||
|
||||
use crate::cli::{load_cargo::load_cargo, Result};
|
||||
|
||||
|
@ -3,9 +3,9 @@
|
||||
use std::{path::Path, sync::Arc};
|
||||
|
||||
use anyhow::Result;
|
||||
use base_db::CrateGraph;
|
||||
use crossbeam_channel::{unbounded, Receiver};
|
||||
use ide::{AnalysisHost, Change};
|
||||
use ide_db::base_db::CrateGraph;
|
||||
use project_model::{CargoConfig, ProcMacroClient, ProjectManifest, ProjectWorkspace};
|
||||
use vfs::{loader::Handle, AbsPath, AbsPathBuf};
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
use ssr::{MatchFinder, SsrPattern, SsrRule};
|
||||
|
||||
pub fn apply_ssr_rules(rules: Vec<SsrRule>) -> Result<()> {
|
||||
use base_db::SourceDatabaseExt;
|
||||
use ide_db::base_db::SourceDatabaseExt;
|
||||
let (host, vfs) = load_cargo(&std::env::current_dir()?, true, true)?;
|
||||
let db = host.raw_database();
|
||||
let mut match_finder = MatchFinder::at_first_file(db)?;
|
||||
@ -26,7 +26,7 @@ pub fn apply_ssr_rules(rules: Vec<SsrRule>) -> Result<()> {
|
||||
/// `debug_snippet`. This is intended for debugging and probably isn't in it's current form useful
|
||||
/// for much else.
|
||||
pub fn search_for_patterns(patterns: Vec<SsrPattern>, debug_snippet: Option<String>) -> Result<()> {
|
||||
use base_db::SourceDatabaseExt;
|
||||
use ide_db::base_db::SourceDatabaseExt;
|
||||
use ide_db::symbol_index::SymbolsDatabase;
|
||||
let (host, _vfs) = load_cargo(&std::env::current_dir()?, true, true)?;
|
||||
let db = host.raw_database();
|
||||
|
@ -1,8 +1,8 @@
|
||||
//! Conversion lsp_types types to rust-analyzer specific ones.
|
||||
use std::convert::TryFrom;
|
||||
|
||||
use base_db::{FileId, FilePosition, FileRange};
|
||||
use ide::{AssistKind, LineCol, LineIndex};
|
||||
use ide_db::base_db::{FileId, FilePosition, FileRange};
|
||||
use syntax::{TextRange, TextSize};
|
||||
use vfs::AbsPathBuf;
|
||||
|
||||
|
@ -5,10 +5,10 @@
|
||||
|
||||
use std::{sync::Arc, time::Instant};
|
||||
|
||||
use base_db::{CrateId, VfsPath};
|
||||
use crossbeam_channel::{unbounded, Receiver, Sender};
|
||||
use flycheck::FlycheckHandle;
|
||||
use ide::{Analysis, AnalysisHost, Change, FileId};
|
||||
use ide_db::base_db::{CrateId, VfsPath};
|
||||
use lsp_types::{SemanticTokens, Url};
|
||||
use parking_lot::{Mutex, RwLock};
|
||||
use project_model::{CargoWorkspace, ProcMacroClient, ProjectWorkspace, Target};
|
||||
|
@ -1,8 +1,8 @@
|
||||
//! Utilities for LSP-related boilerplate code.
|
||||
use std::{error::Error, ops::Range};
|
||||
|
||||
use base_db::Canceled;
|
||||
use ide::LineIndex;
|
||||
use ide_db::base_db::Canceled;
|
||||
use lsp_server::Notification;
|
||||
|
||||
use crate::{from_proto, global_state::GlobalState};
|
||||
|
@ -5,10 +5,10 @@
|
||||
time::{Duration, Instant},
|
||||
};
|
||||
|
||||
use base_db::VfsPath;
|
||||
use crossbeam_channel::{select, Receiver};
|
||||
use ide::PrimeCachesProgress;
|
||||
use ide::{Canceled, FileId};
|
||||
use ide_db::base_db::VfsPath;
|
||||
use lsp_server::{Connection, Notification, Request, Response};
|
||||
use lsp_types::notification::Notification as _;
|
||||
use project_model::ProjectWorkspace;
|
||||
|
@ -1,9 +1,9 @@
|
||||
//! Project loading & configuration updates
|
||||
use std::{mem, sync::Arc};
|
||||
|
||||
use base_db::{CrateGraph, SourceRoot, VfsPath};
|
||||
use flycheck::{FlycheckConfig, FlycheckHandle};
|
||||
use ide::Change;
|
||||
use ide_db::base_db::{CrateGraph, SourceRoot, VfsPath};
|
||||
use project_model::{ProcMacroClient, ProjectWorkspace};
|
||||
use vfs::{file_set::FileSetConfig, AbsPath, AbsPathBuf, ChangeKind};
|
||||
|
||||
|
@ -4,13 +4,13 @@
|
||||
sync::atomic::{AtomicU32, Ordering},
|
||||
};
|
||||
|
||||
use base_db::{FileId, FileRange};
|
||||
use ide::{
|
||||
Assist, AssistKind, CallInfo, CompletionItem, CompletionItemKind, Documentation,
|
||||
FileSystemEdit, Fold, FoldKind, Highlight, HighlightModifier, HighlightTag, HighlightedRange,
|
||||
Indel, InlayHint, InlayKind, InsertTextFormat, LineIndex, Markup, NavigationTarget,
|
||||
ReferenceAccess, ResolvedAssist, Runnable, Severity, SourceChange, SourceFileEdit, TextEdit,
|
||||
};
|
||||
use ide_db::base_db::{FileId, FileRange};
|
||||
use itertools::Itertools;
|
||||
use syntax::{SyntaxKind, TextRange, TextSize};
|
||||
|
||||
@ -809,7 +809,7 @@ fn main() {
|
||||
let completions: Vec<(String, Option<String>)> = analysis
|
||||
.completions(
|
||||
&ide::CompletionConfig::default(),
|
||||
base_db::FilePosition { file_id, offset },
|
||||
ide_db::base_db::FilePosition { file_id, offset },
|
||||
)
|
||||
.unwrap()
|
||||
.unwrap()
|
||||
|
@ -16,7 +16,6 @@ itertools = "0.9.0"
|
||||
|
||||
text_edit = { path = "../text_edit", version = "0.0.0" }
|
||||
syntax = { path = "../syntax", version = "0.0.0" }
|
||||
base_db = { path = "../base_db", version = "0.0.0" }
|
||||
ide_db = { path = "../ide_db", version = "0.0.0" }
|
||||
hir = { path = "../hir", version = "0.0.0" }
|
||||
test_utils = { path = "../test_utils", version = "0.0.0" }
|
||||
|
@ -73,8 +73,8 @@
|
||||
pub use crate::errors::SsrError;
|
||||
pub use crate::matching::Match;
|
||||
use crate::matching::MatchFailureReason;
|
||||
use base_db::{FileId, FilePosition, FileRange};
|
||||
use hir::Semantics;
|
||||
use ide_db::base_db::{FileId, FilePosition, FileRange};
|
||||
use ide_db::source_change::SourceFileEdit;
|
||||
use resolving::ResolvedRule;
|
||||
use rustc_hash::FxHashMap;
|
||||
@ -126,7 +126,7 @@ pub fn in_context(
|
||||
|
||||
/// Constructs an instance using the start of the first file in `db` as the lookup context.
|
||||
pub fn at_first_file(db: &'db ide_db::RootDatabase) -> Result<MatchFinder<'db>, SsrError> {
|
||||
use base_db::SourceDatabaseExt;
|
||||
use ide_db::base_db::SourceDatabaseExt;
|
||||
use ide_db::symbol_index::SymbolsDatabase;
|
||||
if let Some(first_file_id) = db
|
||||
.local_roots()
|
||||
@ -160,7 +160,7 @@ pub fn add_rule(&mut self, rule: SsrRule) -> Result<(), SsrError> {
|
||||
|
||||
/// Finds matches for all added rules and returns edits for all found matches.
|
||||
pub fn edits(&self) -> Vec<SourceFileEdit> {
|
||||
use base_db::SourceDatabaseExt;
|
||||
use ide_db::base_db::SourceDatabaseExt;
|
||||
let mut matches_by_file = FxHashMap::default();
|
||||
for m in self.matches().matches {
|
||||
matches_by_file
|
||||
@ -205,7 +205,7 @@ pub fn matches(&self) -> SsrMatches {
|
||||
/// them, while recording reasons why they don't match. This API is useful for command
|
||||
/// line-based debugging where providing a range is difficult.
|
||||
pub fn debug_where_text_equal(&self, file_id: FileId, snippet: &str) -> Vec<MatchDebugInfo> {
|
||||
use base_db::SourceDatabaseExt;
|
||||
use ide_db::base_db::SourceDatabaseExt;
|
||||
let file = self.sema.parse(file_id);
|
||||
let mut res = Vec::new();
|
||||
let file_text = self.sema.db.file_text(file_id);
|
||||
|
@ -6,8 +6,8 @@
|
||||
resolving::{ResolvedPattern, ResolvedRule, UfcsCallInfo},
|
||||
SsrMatches,
|
||||
};
|
||||
use base_db::FileRange;
|
||||
use hir::Semantics;
|
||||
use ide_db::base_db::FileRange;
|
||||
use rustc_hash::FxHashMap;
|
||||
use std::{cell::Cell, iter::Peekable};
|
||||
use syntax::ast::{AstNode, AstToken};
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
use crate::errors::error;
|
||||
use crate::{parsing, SsrError};
|
||||
use base_db::FilePosition;
|
||||
use ide_db::base_db::FilePosition;
|
||||
use parsing::Placeholder;
|
||||
use rustc_hash::FxHashMap;
|
||||
use syntax::{ast, SmolStr, SyntaxKind, SyntaxNode, SyntaxToken};
|
||||
|
@ -5,7 +5,7 @@
|
||||
resolving::{ResolvedPath, ResolvedPattern, ResolvedRule},
|
||||
Match, MatchFinder,
|
||||
};
|
||||
use base_db::{FileId, FileRange};
|
||||
use ide_db::base_db::{FileId, FileRange};
|
||||
use ide_db::{
|
||||
defs::Definition,
|
||||
search::{Reference, SearchScope},
|
||||
@ -145,7 +145,7 @@ fn slow_scan(&self, rule: &ResolvedRule, matches_out: &mut Vec<Match>) {
|
||||
fn search_files_do(&self, mut callback: impl FnMut(FileId)) {
|
||||
if self.restrict_ranges.is_empty() {
|
||||
// Unrestricted search.
|
||||
use base_db::SourceDatabaseExt;
|
||||
use ide_db::base_db::SourceDatabaseExt;
|
||||
use ide_db::symbol_index::SymbolsDatabase;
|
||||
for &root in self.sema.db.local_roots().iter() {
|
||||
let sr = self.sema.db.source_root(root);
|
||||
|
@ -1,6 +1,6 @@
|
||||
use crate::{MatchFinder, SsrRule};
|
||||
use base_db::{salsa::Durability, FileId, FilePosition, FileRange, SourceDatabaseExt};
|
||||
use expect_test::{expect, Expect};
|
||||
use ide_db::base_db::{salsa::Durability, FileId, FilePosition, FileRange, SourceDatabaseExt};
|
||||
use rustc_hash::FxHashSet;
|
||||
use std::sync::Arc;
|
||||
use test_utils::{mark, RangeOrOffset};
|
||||
@ -62,7 +62,7 @@ fn parser_undefined_placeholder_in_replacement() {
|
||||
/// `code` may optionally contain a cursor marker `<|>`. If it doesn't, then the position will be
|
||||
/// the start of the file. If there's a second cursor marker, then we'll return a single range.
|
||||
pub(crate) fn single_file(code: &str) -> (ide_db::RootDatabase, FilePosition, Vec<FileRange>) {
|
||||
use base_db::fixture::WithFixture;
|
||||
use ide_db::base_db::fixture::WithFixture;
|
||||
use ide_db::symbol_index::SymbolsDatabase;
|
||||
let (mut db, file_id, range_or_offset) = if code.contains(test_utils::CURSOR_MARKER) {
|
||||
ide_db::RootDatabase::with_range_or_offset(code)
|
||||
@ -83,7 +83,7 @@ pub(crate) fn single_file(code: &str) -> (ide_db::RootDatabase, FilePosition, Ve
|
||||
}
|
||||
}
|
||||
let mut local_roots = FxHashSet::default();
|
||||
local_roots.insert(base_db::fixture::WORKSPACE);
|
||||
local_roots.insert(ide_db::base_db::fixture::WORKSPACE);
|
||||
db.set_local_roots_with_durability(Arc::new(local_roots), Durability::HIGH);
|
||||
(db, position, selections)
|
||||
}
|
||||
|
@ -7,7 +7,7 @@
|
||||
use parser::SyntaxKind;
|
||||
|
||||
use crate::{
|
||||
ast::{self, support, AstNode, NameOwner, SyntaxNode},
|
||||
ast::{self, support, token_ext::HasStringValue, AstNode, AstToken, NameOwner, SyntaxNode},
|
||||
SmolStr, SyntaxElement, SyntaxToken, T,
|
||||
};
|
||||
|
||||
@ -53,8 +53,16 @@ pub fn as_simple_call(&self) -> Option<(SmolStr, ast::TokenTree)> {
|
||||
pub fn as_simple_key_value(&self) -> Option<(SmolStr, SmolStr)> {
|
||||
let lit = self.literal()?;
|
||||
let key = self.simple_name()?;
|
||||
// FIXME: escape? raw string?
|
||||
let value = lit.syntax().first_token()?.text().trim_matches('"').into();
|
||||
let value_token = lit.syntax().first_token()?;
|
||||
|
||||
let value: SmolStr = if let Some(s) = ast::String::cast(value_token.clone()) {
|
||||
s.value()?.into()
|
||||
} else if let Some(s) = ast::RawString::cast(value_token) {
|
||||
s.value()?.into()
|
||||
} else {
|
||||
return None;
|
||||
};
|
||||
|
||||
Some((key, value))
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user