1
+ use ide_db:: imports:: insert_use:: ImportScope ;
1
2
use syntax:: {
2
3
ast:: { self , make, AstNode , HasArgList } ,
3
4
TextRange ,
@@ -17,6 +18,8 @@ use crate::{AssistContext, AssistId, AssistKind, Assists};
17
18
// ```
18
19
// ->
19
20
// ```
21
+ // use std::ops::Add;
22
+ //
20
23
// fn main() {
21
24
// 1.add(2);
22
25
// }
@@ -38,7 +41,7 @@ pub(crate) fn unqualify_method_call(acc: &mut Assists, ctx: &AssistContext<'_>)
38
41
let first_arg = args_iter. next ( ) ?;
39
42
let second_arg = args_iter. next ( ) ;
40
43
41
- _ = path. qualifier ( ) ?;
44
+ let qualifier = path. qualifier ( ) ?;
42
45
let method_name = path. segment ( ) ?. name_ref ( ) ?;
43
46
44
47
let res = ctx. sema . resolve_path ( & path) ?;
@@ -76,10 +79,44 @@ pub(crate) fn unqualify_method_call(acc: &mut Assists, ctx: &AssistContext<'_>)
76
79
edit. insert ( close, ")" ) ;
77
80
}
78
81
edit. replace ( replace_comma, format ! ( ".{method_name}(" ) ) ;
82
+ add_import ( qualifier, ctx, edit) ;
79
83
} ,
80
84
)
81
85
}
82
86
87
+ fn add_import (
88
+ qualifier : ast:: Path ,
89
+ ctx : & AssistContext < ' _ > ,
90
+ edit : & mut ide_db:: source_change:: SourceChangeBuilder ,
91
+ ) {
92
+ // for `<i32 as std::ops::Add>`
93
+ let path_type =
94
+ qualifier. segment ( ) . unwrap ( ) . syntax ( ) . children ( ) . filter_map ( ast:: PathType :: cast) . last ( ) ;
95
+ let import = match path_type {
96
+ Some ( it) => it. path ( ) . unwrap ( ) ,
97
+ None => qualifier,
98
+ } ;
99
+
100
+ // in case for `<_>`
101
+ if import. coloncolon_token ( ) . is_none ( ) {
102
+ return ;
103
+ }
104
+
105
+ let scope = ide_db:: imports:: insert_use:: ImportScope :: find_insert_use_container (
106
+ import. syntax ( ) ,
107
+ & ctx. sema ,
108
+ ) ;
109
+
110
+ if let Some ( scope) = scope {
111
+ let scope = match scope {
112
+ ImportScope :: File ( it) => ImportScope :: File ( edit. make_mut ( it) ) ,
113
+ ImportScope :: Module ( it) => ImportScope :: Module ( edit. make_mut ( it) ) ,
114
+ ImportScope :: Block ( it) => ImportScope :: Block ( edit. make_mut ( it) ) ,
115
+ } ;
116
+ ide_db:: imports:: insert_use:: insert_use ( & scope, import, & ctx. config . insert_use ) ;
117
+ }
118
+ }
119
+
83
120
fn needs_parens_as_receiver ( expr : & ast:: Expr ) -> bool {
84
121
// Make `(expr).dummy()`
85
122
let dummy_call = make:: expr_method_call (
@@ -127,6 +164,8 @@ fn f() { S.f(S); }"#,
127
164
//- minicore: add
128
165
fn f() { <u32 as core::ops::Add>::$0add(2, 2); }"# ,
129
166
r#"
167
+ use core::ops::Add;
168
+
130
169
fn f() { 2.add(2); }"# ,
131
170
) ;
132
171
@@ -136,6 +175,8 @@ fn f() { 2.add(2); }"#,
136
175
//- minicore: add
137
176
fn f() { core::ops::Add::$0add(2, 2); }"# ,
138
177
r#"
178
+ use core::ops::Add;
179
+
139
180
fn f() { 2.add(2); }"# ,
140
181
) ;
141
182
@@ -179,6 +220,8 @@ impl core::ops::Deref for S {
179
220
}
180
221
fn f() { core::ops::Deref::$0deref(&S); }"# ,
181
222
r#"
223
+ use core::ops::Deref;
224
+
182
225
struct S;
183
226
impl core::ops::Deref for S {
184
227
type Target = S;
0 commit comments