mirror of
https://github.com/rust-lang/rust-analyzer
synced 2025-01-12 21:28:51 +00:00
Add imports in auto completion
This commit is contained in:
parent
0a658c4a97
commit
f62e8616c8
14 changed files with 199 additions and 130 deletions
160
Cargo.lock
generated
160
Cargo.lock
generated
|
@ -2,9 +2,9 @@
|
|||
# It is not intended for manual editing.
|
||||
[[package]]
|
||||
name = "addr2line"
|
||||
version = "0.14.0"
|
||||
version = "0.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7c0929d69e78dd9bf5408269919fcbcaeb2e35e5d43e5815517cdc6a8e11a423"
|
||||
checksum = "1b6a2d3371669ab3ca9797670853d61402b03d0b4b9ebf33d677dfa720203072"
|
||||
dependencies = [
|
||||
"gimli",
|
||||
]
|
||||
|
@ -26,9 +26,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.34"
|
||||
version = "1.0.33"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bf8dcb5b4bbaa28653b647d8c77bd4ed40183b48882e130c1f1ffb73de069fd7"
|
||||
checksum = "a1fd36ffbb1fb7c834eac128ea8d0e310c5aeb635548f9d58861e1308d46e71c"
|
||||
|
||||
[[package]]
|
||||
name = "anymap"
|
||||
|
@ -42,9 +42,9 @@ version = "0.0.0"
|
|||
|
||||
[[package]]
|
||||
name = "arrayvec"
|
||||
version = "0.5.2"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b"
|
||||
checksum = "cff77d8686867eceff3105329d4698d96c2391c176d5d03adc90c7389162b5b8"
|
||||
|
||||
[[package]]
|
||||
name = "assists"
|
||||
|
@ -81,9 +81,9 @@ checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
|
|||
|
||||
[[package]]
|
||||
name = "backtrace"
|
||||
version = "0.3.54"
|
||||
version = "0.3.53"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2baad346b2d4e94a24347adeee9c7a93f412ee94b9cc26e5b59dea23848e9f28"
|
||||
checksum = "707b586e0e2f247cbde68cdd2c3ce69ea7b7be43e1c5b426e37c9319c4b9838e"
|
||||
dependencies = [
|
||||
"addr2line",
|
||||
"cfg-if 1.0.0",
|
||||
|
@ -132,7 +132,7 @@ version = "0.12.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d5a5f7b42f606b7f23674f6f4d877628350682bc40687d3fae65679a58d55345"
|
||||
dependencies = [
|
||||
"semver 0.11.0",
|
||||
"semver",
|
||||
"serde",
|
||||
"serde_json",
|
||||
]
|
||||
|
@ -255,6 +255,7 @@ version = "0.0.0"
|
|||
dependencies = [
|
||||
"assists",
|
||||
"base_db",
|
||||
"either",
|
||||
"expect-test",
|
||||
"hir",
|
||||
"ide_db",
|
||||
|
@ -270,17 +271,17 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "const_fn"
|
||||
version = "0.4.3"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c478836e029dcef17fb47c89023448c64f781a046e0300e257ad8225ae59afab"
|
||||
checksum = "ce90df4c658c62f12d78f7508cf92f9173e5184a539c10bfe54a3107b3ffd0f2"
|
||||
|
||||
[[package]]
|
||||
name = "crc32fast"
|
||||
version = "1.2.1"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a"
|
||||
checksum = "ba125de2af0df55319f41944744ad91c71113bf74a4646efff39afe1f6842db1"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"cfg-if 0.1.10",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -417,11 +418,11 @@ checksum = "37ab347416e802de484e4d03c7316c48f1ecb56574dfd4a46a80f173ce1de04d"
|
|||
|
||||
[[package]]
|
||||
name = "flate2"
|
||||
version = "1.0.19"
|
||||
version = "1.0.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7411863d55df97a419aa64cb4d2f167103ea9d767e2c54a1868b7ac3f6b47129"
|
||||
checksum = "da80be589a72651dcda34d8b35bcdc9b7254ad06325611074d9cc0fbb19f60ee"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"cfg-if 0.1.10",
|
||||
"crc32fast",
|
||||
"libc",
|
||||
"miniz_oxide",
|
||||
|
@ -470,9 +471,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "fst"
|
||||
version = "0.4.5"
|
||||
version = "0.4.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d79238883cf0307100b90aba4a755d8051a3182305dfe7f649a1e9dc0517006f"
|
||||
checksum = "a7293de202dbfe786c0b3fe6110a027836c5438ed06db7b715c9955ff4bfea51"
|
||||
|
||||
[[package]]
|
||||
name = "fuchsia-zircon"
|
||||
|
@ -490,24 +491,11 @@ version = "0.3.3"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
|
||||
|
||||
[[package]]
|
||||
name = "generator"
|
||||
version = "0.6.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8cdc09201b2e8ca1b19290cf7e65de2246b8e91fb6874279722189c4de7b94dc"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
"log",
|
||||
"rustc_version",
|
||||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gimli"
|
||||
version = "0.23.0"
|
||||
version = "0.22.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f6503fe142514ca4799d4c26297c4248239fe8838d827db6bd6065c6ed29a6ce"
|
||||
checksum = "aaf91faf136cb47367fa430cd46e37a788775e7fa104f8b4bcb3861dc389b724"
|
||||
|
||||
[[package]]
|
||||
name = "goblin"
|
||||
|
@ -735,11 +723,11 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "instant"
|
||||
version = "0.1.8"
|
||||
version = "0.1.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cb1fc4429a33e1f80d41dc9fea4d108a88bec1de8053878898ae448a0b52f613"
|
||||
checksum = "63312a18f7ea8760cdd0a7c5aac1a619752a246b833545e3e36d1f81f7cd9e66"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"cfg-if 0.1.10",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -796,17 +784,17 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
|
|||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.80"
|
||||
version = "0.2.79"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4d58d1b70b004888f764dfbf6a26a3b0342a1632d33968e4a179d8011c760614"
|
||||
checksum = "2448f6066e80e3bfc792e9c98bf705b4b0fc6e8ef5b43e5889aff0eaa9c58743"
|
||||
|
||||
[[package]]
|
||||
name = "libloading"
|
||||
version = "0.6.5"
|
||||
version = "0.6.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1090080fe06ec2648d0da3881d9453d97e71a45f00eb179af7fdd7e3f686fdb0"
|
||||
checksum = "3557c9384f7f757f6d139cd3a4c62ef4e850696c16bf27924a5538c8a09717a1"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"cfg-if 0.1.10",
|
||||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
|
@ -837,19 +825,6 @@ dependencies = [
|
|||
"cfg-if 0.1.10",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "loom"
|
||||
version = "0.3.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a0e8460f2f2121162705187214720353c517b97bdfb3494c0b1e33d83ebe4bed"
|
||||
dependencies = [
|
||||
"cfg-if 0.1.10",
|
||||
"generator",
|
||||
"scoped-tls",
|
||||
"serde",
|
||||
"serde_json",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lsp-server"
|
||||
version = "0.4.1"
|
||||
|
@ -912,9 +887,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.3.4"
|
||||
version = "2.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525"
|
||||
checksum = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400"
|
||||
|
||||
[[package]]
|
||||
name = "memmap"
|
||||
|
@ -1010,9 +985,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "notify"
|
||||
version = "5.0.0-pre.4"
|
||||
version = "5.0.0-pre.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a8b946889dfdad884379cd56367d93b6d0ce8889cc027d26a69a3a31c0a03bb5"
|
||||
checksum = "77d03607cf88b4b160ba0e9ed425fff3cee3b55ac813f0c685b3a3772da37d0e"
|
||||
dependencies = [
|
||||
"anymap",
|
||||
"bitflags",
|
||||
|
@ -1030,9 +1005,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "num-integer"
|
||||
version = "0.1.44"
|
||||
version = "0.1.43"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db"
|
||||
checksum = "8d59457e662d541ba17869cf51cf177c0b5f0cbf476c66bdc90bf1edac4f875b"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-traits",
|
||||
|
@ -1040,9 +1015,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.14"
|
||||
version = "0.2.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290"
|
||||
checksum = "ac267bcc07f48ee5f8935ab0d24f316fb722d7a1292e2913f0cc196b29ffd611"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
@ -1059,9 +1034,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "object"
|
||||
version = "0.22.0"
|
||||
version = "0.21.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8d3b63360ec3cb337817c2dbd47ab4a0f170d285d8e5a2064600f3def1402397"
|
||||
checksum = "37fd5004feb2ce328a52b0b3d01dbf4ffff72583493900ed15f22d4111c51693"
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
|
@ -1310,9 +1285,9 @@ checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce"
|
|||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.4.2"
|
||||
version = "1.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "38cf2c13ed4745de91a5eb834e11c00bcc3709e773173b2ce4c56c9fbde04b9c"
|
||||
checksum = "8963b85b8ce3074fecffde43b4b0dded83ce2f367dc8d363afc56679f3ee820b"
|
||||
dependencies = [
|
||||
"regex-syntax",
|
||||
]
|
||||
|
@ -1329,9 +1304,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.6.21"
|
||||
version = "0.6.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3b181ba2dcf07aaccad5448e8ead58db5b742cf85dfe035e2227f137a539a189"
|
||||
checksum = "8cab7a364d15cde1e505267766a2d3c4e22a843e1a601f0fa7564c0f82ced11c"
|
||||
|
||||
[[package]]
|
||||
name = "rowan"
|
||||
|
@ -1404,9 +1379,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "rustc-demangle"
|
||||
version = "0.1.18"
|
||||
version = "0.1.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6e3bad0ee36814ca07d7968269dd4b7ec89ec2da10c4bb613928d3077083c232"
|
||||
checksum = "b2610b7f643d18c87dff3b489950269617e6601a51f1f05aa5daefee36f64f0b"
|
||||
|
||||
[[package]]
|
||||
name = "rustc-hash"
|
||||
|
@ -1414,15 +1389,6 @@ version = "1.1.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
|
||||
|
||||
[[package]]
|
||||
name = "rustc_version"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
|
||||
dependencies = [
|
||||
"semver 0.9.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.5"
|
||||
|
@ -1490,40 +1456,25 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "scroll_derive"
|
||||
version = "0.10.4"
|
||||
version = "0.10.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b12bd20b94c7cdfda8c7ba9b92ad0d9a56e3fa018c25fca83b51aa664c9b4c0d"
|
||||
checksum = "6dfde5d1531034db129e95c76ac857e2baecea3443579d493d02224950b0fb6d"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "semver"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
|
||||
dependencies = [
|
||||
"semver-parser 0.7.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "semver"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6"
|
||||
dependencies = [
|
||||
"semver-parser 0.10.1",
|
||||
"semver-parser",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "semver-parser"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
|
||||
|
||||
[[package]]
|
||||
name = "semver-parser"
|
||||
version = "0.10.1"
|
||||
|
@ -1577,12 +1528,11 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "sharded-slab"
|
||||
version = "0.1.0"
|
||||
version = "0.0.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7b4921be914e16899a80adefb821f8ddb7974e3f1250223575a44ed994882127"
|
||||
checksum = "06d5a3f5166fb5b42a5439f2eee8b9de149e235961e3eb21c5808fc3ea17ff3e"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"loom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1626,9 +1576,9 @@ version = "0.0.0"
|
|||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.48"
|
||||
version = "1.0.45"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cc371affeffc477f42a221a1e4297aedcea33d47d19b61455588bd9d8f6b19ac"
|
||||
checksum = "ea9c5432ff16d6152371f808fb5a871cd67368171b09bb21b43df8e4a47a3556"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -1805,9 +1755,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "tracing-subscriber"
|
||||
version = "0.2.15"
|
||||
version = "0.2.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a1fa8f0c8f4c594e4fc9debc1990deab13238077271ba84dd853d54902ee3401"
|
||||
checksum = "4ef0a5e15477aa303afbfac3a44cba9b6430fdaad52423b1e6c0dbbe28c3eedd"
|
||||
dependencies = [
|
||||
"ansi_term",
|
||||
"chrono",
|
||||
|
|
|
@ -98,7 +98,8 @@ pub(crate) fn auto_import(acc: &mut Assists, ctx: &AssistContext) -> Option<()>
|
|||
|
||||
let range = ctx.sema.original_range(import_assets.syntax_under_caret()).range;
|
||||
let group = import_group_message(import_assets.import_candidate());
|
||||
let scope = ImportScope::find_insert_use_container(import_assets.syntax_under_caret(), ctx)?;
|
||||
let scope =
|
||||
ImportScope::find_insert_use_container(import_assets.syntax_under_caret(), &ctx.sema)?;
|
||||
for (import, _) in proposed_imports {
|
||||
acc.add_group(
|
||||
&group,
|
||||
|
|
|
@ -143,8 +143,7 @@ fn insert_import(
|
|||
if let Some(mut mod_path) = mod_path {
|
||||
mod_path.segments.pop();
|
||||
mod_path.segments.push(variant_hir_name.clone());
|
||||
let scope = ImportScope::find_insert_use_container(scope_node, ctx)?;
|
||||
|
||||
let scope = ImportScope::find_insert_use_container(scope_node, &ctx.sema)?;
|
||||
*rewriter += insert_use(&scope, mod_path_to_ast(&mod_path), ctx.config.insert_use.merge);
|
||||
}
|
||||
Some(())
|
||||
|
|
|
@ -34,7 +34,7 @@ pub(crate) fn replace_qualified_name_with_use(
|
|||
}
|
||||
|
||||
let target = path.syntax().text_range();
|
||||
let scope = ImportScope::find_insert_use_container(path.syntax(), ctx)?;
|
||||
let scope = ImportScope::find_insert_use_container(path.syntax(), &ctx.sema)?;
|
||||
let syntax = scope.as_syntax_node();
|
||||
acc.add(
|
||||
AssistId("replace_qualified_name_with_use", AssistKind::RefactorRewrite),
|
||||
|
|
|
@ -21,8 +21,7 @@ use crate::{
|
|||
ast_transform::{self, AstTransform, QualifyPaths, SubstituteTypeParams},
|
||||
};
|
||||
|
||||
pub use insert_use::MergeBehaviour;
|
||||
pub(crate) use insert_use::{insert_use, ImportScope};
|
||||
pub use insert_use::{insert_use, ImportScope, MergeBehaviour};
|
||||
|
||||
pub fn mod_path_to_ast(path: &hir::ModPath) -> ast::Path {
|
||||
let mut segments = Vec::new();
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
//! Handle syntactic aspects of inserting a new `use`.
|
||||
use std::{cmp::Ordering, iter::successors};
|
||||
|
||||
use hir::Semantics;
|
||||
use ide_db::RootDatabase;
|
||||
use itertools::{EitherOrBoth, Itertools};
|
||||
use syntax::{
|
||||
algo::SyntaxRewriter,
|
||||
|
@ -14,7 +16,7 @@ use syntax::{
|
|||
use test_utils::mark;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) enum ImportScope {
|
||||
pub enum ImportScope {
|
||||
File(ast::SourceFile),
|
||||
Module(ast::ItemList),
|
||||
}
|
||||
|
@ -31,14 +33,14 @@ impl ImportScope {
|
|||
}
|
||||
|
||||
/// Determines the containing syntax node in which to insert a `use` statement affecting `position`.
|
||||
pub(crate) fn find_insert_use_container(
|
||||
pub fn find_insert_use_container(
|
||||
position: &SyntaxNode,
|
||||
ctx: &crate::assist_context::AssistContext,
|
||||
sema: &Semantics<'_, RootDatabase>,
|
||||
) -> Option<Self> {
|
||||
ctx.sema.ancestors_with_macros(position.clone()).find_map(Self::from)
|
||||
sema.ancestors_with_macros(position.clone()).find_map(Self::from)
|
||||
}
|
||||
|
||||
pub(crate) fn as_syntax_node(&self) -> &SyntaxNode {
|
||||
pub fn as_syntax_node(&self) -> &SyntaxNode {
|
||||
match self {
|
||||
ImportScope::File(file) => file.syntax(),
|
||||
ImportScope::Module(item_list) => item_list.syntax(),
|
||||
|
@ -88,7 +90,7 @@ fn is_inner_comment(token: SyntaxToken) -> bool {
|
|||
}
|
||||
|
||||
/// Insert an import path into the given file/node. A `merge` value of none indicates that no import merging is allowed to occur.
|
||||
pub(crate) fn insert_use<'a>(
|
||||
pub fn insert_use<'a>(
|
||||
scope: &ImportScope,
|
||||
path: ast::Path,
|
||||
merge: Option<MergeBehaviour>,
|
||||
|
|
|
@ -13,6 +13,7 @@ doctest = false
|
|||
itertools = "0.9.0"
|
||||
log = "0.4.8"
|
||||
rustc-hash = "1.1.0"
|
||||
either = "1.6.1"
|
||||
|
||||
assists = { path = "../assists", version = "0.0.0" }
|
||||
stdx = { path = "../stdx", version = "0.0.0" }
|
||||
|
@ -21,6 +22,7 @@ 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" }
|
||||
profile = { path = "../profile", version = "0.0.0" }
|
||||
assists = { path = "../assists", version = "0.0.0" }
|
||||
test_utils = { path = "../test_utils", version = "0.0.0" }
|
||||
|
||||
# completions crate should depend only on the top-level `hir` package. if you need
|
||||
|
|
|
@ -13,6 +13,7 @@ pub(crate) mod postfix;
|
|||
pub(crate) mod macro_in_item_position;
|
||||
pub(crate) mod trait_impl;
|
||||
pub(crate) mod mod_;
|
||||
pub(crate) mod complete_magic;
|
||||
|
||||
use hir::{ModPath, ScopeDef, Type};
|
||||
|
||||
|
|
114
crates/completion/src/completions/complete_magic.rs
Normal file
114
crates/completion/src/completions/complete_magic.rs
Normal file
|
@ -0,0 +1,114 @@
|
|||
//! TODO kb move this into the complete_unqualified_path when starts to work properly
|
||||
|
||||
use assists::utils::{insert_use, mod_path_to_ast, ImportScope, MergeBehaviour};
|
||||
use hir::Query;
|
||||
use itertools::Itertools;
|
||||
use syntax::AstNode;
|
||||
use text_edit::TextEdit;
|
||||
|
||||
use crate::{context::CompletionContext, item::CompletionKind, CompletionItem, CompletionItemKind};
|
||||
|
||||
use super::Completions;
|
||||
|
||||
pub(crate) fn complete_magic(acc: &mut Completions, ctx: &CompletionContext) -> Option<()> {
|
||||
if !(ctx.is_trivial_path || ctx.is_pat_binding_or_const) {
|
||||
return None;
|
||||
}
|
||||
let current_module = ctx.scope.module()?;
|
||||
let anchor = ctx.name_ref_syntax.as_ref()?;
|
||||
let import_scope = ImportScope::find_insert_use_container(anchor.syntax(), &ctx.sema)?;
|
||||
// TODO kb now this is the whole file, which is not disjoint with any other change in the same file, fix it
|
||||
// otherwise it's impossible to correctly add the use statement and also change the completed text into something more meaningful
|
||||
let import_syntax = import_scope.as_syntax_node();
|
||||
|
||||
// TODO kb consider heuristics, such as "don't show `hash_map` import if `HashMap` is the import for completion"
|
||||
// TODO kb module functions are not completed, consider `std::io::stdin` one
|
||||
let potential_import_name = ctx.token.to_string();
|
||||
|
||||
let possible_imports = ctx
|
||||
.krate?
|
||||
// TODO kb use imports_locator instead?
|
||||
.query_external_importables(ctx.db, Query::new(&potential_import_name).limit(40))
|
||||
.unique()
|
||||
.filter_map(|import_candidate| match import_candidate {
|
||||
either::Either::Left(module_def) => current_module.find_use_path(ctx.db, module_def),
|
||||
either::Either::Right(macro_def) => current_module.find_use_path(ctx.db, macro_def),
|
||||
})
|
||||
.filter_map(|mod_path| {
|
||||
let correct_qualifier = mod_path.segments.last()?.to_string();
|
||||
let rewriter =
|
||||
insert_use(&import_scope, mod_path_to_ast(&mod_path), Some(MergeBehaviour::Full));
|
||||
let rewritten_node = rewriter.rewrite(import_syntax);
|
||||
let insert_use_edit =
|
||||
TextEdit::replace(import_syntax.text_range(), rewritten_node.to_string());
|
||||
let mut completion_edit =
|
||||
TextEdit::replace(anchor.syntax().text_range(), correct_qualifier);
|
||||
completion_edit.union(insert_use_edit).expect("TODO kb");
|
||||
|
||||
let completion_item: CompletionItem = CompletionItem::new(
|
||||
CompletionKind::Magic,
|
||||
ctx.source_range(),
|
||||
mod_path.to_string(),
|
||||
)
|
||||
.kind(CompletionItemKind::Struct)
|
||||
.text_edit(completion_edit)
|
||||
.into();
|
||||
Some(completion_item)
|
||||
});
|
||||
acc.add_all(possible_imports);
|
||||
|
||||
Some(())
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use expect_test::{expect, Expect};
|
||||
|
||||
use crate::{
|
||||
item::CompletionKind,
|
||||
test_utils::{check_edit, completion_list},
|
||||
};
|
||||
|
||||
fn check(ra_fixture: &str, expect: Expect) {
|
||||
let actual = completion_list(ra_fixture, CompletionKind::Magic);
|
||||
expect.assert_eq(&actual)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn case_insensitive_magic_completion_works() {
|
||||
check(
|
||||
r#"
|
||||
//- /lib.rs crate:dep
|
||||
pub struct TestStruct;
|
||||
|
||||
//- /main.rs crate:main deps:dep
|
||||
fn main() {
|
||||
teru<|>
|
||||
}
|
||||
"#,
|
||||
expect![[r#"
|
||||
st dep::TestStruct
|
||||
"#]],
|
||||
);
|
||||
|
||||
check_edit(
|
||||
"dep::TestStruct",
|
||||
r#"
|
||||
//- /lib.rs crate:dep
|
||||
pub struct TestStruct;
|
||||
|
||||
//- /main.rs crate:main deps:dep
|
||||
fn main() {
|
||||
teru<|>
|
||||
}
|
||||
"#,
|
||||
r#"
|
||||
use dep::TestStruct;
|
||||
|
||||
fn main() {
|
||||
TestStruct
|
||||
}
|
||||
"#,
|
||||
);
|
||||
}
|
||||
}
|
|
@ -31,6 +31,7 @@ pub struct CompletionItem {
|
|||
///
|
||||
/// Typically, replaces `source_range` with new identifier.
|
||||
text_edit: TextEdit,
|
||||
|
||||
insert_text_format: InsertTextFormat,
|
||||
|
||||
/// What item (struct, function, etc) are we completing.
|
||||
|
|
|
@ -118,6 +118,7 @@ pub fn completions(
|
|||
completions::macro_in_item_position::complete_macro_in_item_position(&mut acc, &ctx);
|
||||
completions::trait_impl::complete_trait_impl(&mut acc, &ctx);
|
||||
completions::mod_::complete_mod(&mut acc, &ctx);
|
||||
completions::complete_magic::complete_magic(&mut acc, &ctx);
|
||||
|
||||
Some(acc)
|
||||
}
|
||||
|
|
|
@ -110,15 +110,9 @@ impl Crate {
|
|||
pub fn query_external_importables(
|
||||
self,
|
||||
db: &dyn DefDatabase,
|
||||
query: &str,
|
||||
query: import_map::Query,
|
||||
) -> impl Iterator<Item = Either<ModuleDef, MacroDef>> {
|
||||
import_map::search_dependencies(
|
||||
db,
|
||||
self.into(),
|
||||
import_map::Query::new(query).anchor_end().case_sensitive().limit(40),
|
||||
)
|
||||
.into_iter()
|
||||
.map(|item| match item {
|
||||
import_map::search_dependencies(db, self.into(), query).into_iter().map(|item| match item {
|
||||
ItemInNs::Types(mod_id) | ItemInNs::Values(mod_id) => Either::Left(mod_id.into()),
|
||||
ItemInNs::Macros(mac_id) => Either::Right(mac_id.into()),
|
||||
})
|
||||
|
|
|
@ -49,6 +49,7 @@ pub use hir_def::{
|
|||
builtin_type::BuiltinType,
|
||||
docs::Documentation,
|
||||
find_path::PrefixKind,
|
||||
import_map::Query,
|
||||
item_scope::ItemInNs,
|
||||
nameres::ModuleSource,
|
||||
path::{ModPath, PathKind},
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
//! This module contains an import search funcionality that is provided to the assists module.
|
||||
//! Later, this should be moved away to a separate crate that is accessible from the assists module.
|
||||
|
||||
use hir::{Crate, MacroDef, ModuleDef, Semantics};
|
||||
use hir::{Crate, MacroDef, ModuleDef, Query as ImportMapQuery, Semantics};
|
||||
use syntax::{ast, AstNode, SyntaxKind::NAME};
|
||||
|
||||
use crate::{
|
||||
defs::{Definition, NameClass},
|
||||
symbol_index::{self, FileSymbol, Query},
|
||||
symbol_index::{self, FileSymbol, Query as SymbolQuery},
|
||||
RootDatabase,
|
||||
};
|
||||
use either::Either;
|
||||
|
@ -21,12 +21,16 @@ pub fn find_imports<'a>(
|
|||
let db = sema.db;
|
||||
|
||||
// Query dependencies first.
|
||||
let mut candidates: FxHashSet<_> =
|
||||
krate.query_external_importables(db, name_to_import).collect();
|
||||
let mut candidates: FxHashSet<_> = krate
|
||||
.query_external_importables(
|
||||
db,
|
||||
ImportMapQuery::new(name_to_import).anchor_end().case_sensitive().limit(40),
|
||||
)
|
||||
.collect();
|
||||
|
||||
// Query the local crate using the symbol index.
|
||||
let local_results = {
|
||||
let mut query = Query::new(name_to_import.to_string());
|
||||
let mut query = SymbolQuery::new(name_to_import.to_string());
|
||||
query.exact();
|
||||
query.limit(40);
|
||||
symbol_index::crate_symbols(db, krate.into(), query)
|
||||
|
|
Loading…
Reference in a new issue