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,51 @@ 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
+ if let Some ( path_segment) = qualifier. segment ( ) {
93
+ // for `<i32 as std::ops::Add>`
94
+ let path_type = path_segment. syntax ( ) . children ( ) . filter_map ( ast:: PathType :: cast) . last ( ) ;
95
+ let import = match path_type {
96
+ Some ( it) => {
97
+ if let Some ( path) = it. path ( ) {
98
+ path
99
+ } else {
100
+ return ;
101
+ }
102
+ }
103
+ None => qualifier,
104
+ } ;
105
+
106
+ // in case for `<_>`
107
+ if import. coloncolon_token ( ) . is_none ( ) {
108
+ return ;
109
+ }
110
+
111
+ let scope = ide_db:: imports:: insert_use:: ImportScope :: find_insert_use_container (
112
+ import. syntax ( ) ,
113
+ & ctx. sema ,
114
+ ) ;
115
+
116
+ if let Some ( scope) = scope {
117
+ let scope = match scope {
118
+ ImportScope :: File ( it) => ImportScope :: File ( edit. make_mut ( it) ) ,
119
+ ImportScope :: Module ( it) => ImportScope :: Module ( edit. make_mut ( it) ) ,
120
+ ImportScope :: Block ( it) => ImportScope :: Block ( edit. make_mut ( it) ) ,
121
+ } ;
122
+ ide_db:: imports:: insert_use:: insert_use ( & scope, import, & ctx. config . insert_use ) ;
123
+ }
124
+ }
125
+ }
126
+
83
127
fn needs_parens_as_receiver ( expr : & ast:: Expr ) -> bool {
84
128
// Make `(expr).dummy()`
85
129
let dummy_call = make:: expr_method_call (
@@ -127,6 +171,8 @@ fn f() { S.f(S); }"#,
127
171
//- minicore: add
128
172
fn f() { <u32 as core::ops::Add>::$0add(2, 2); }"# ,
129
173
r#"
174
+ use core::ops::Add;
175
+
130
176
fn f() { 2.add(2); }"# ,
131
177
) ;
132
178
@@ -136,6 +182,8 @@ fn f() { 2.add(2); }"#,
136
182
//- minicore: add
137
183
fn f() { core::ops::Add::$0add(2, 2); }"# ,
138
184
r#"
185
+ use core::ops::Add;
186
+
139
187
fn f() { 2.add(2); }"# ,
140
188
) ;
141
189
@@ -179,6 +227,8 @@ impl core::ops::Deref for S {
179
227
}
180
228
fn f() { core::ops::Deref::$0deref(&S); }"# ,
181
229
r#"
230
+ use core::ops::Deref;
231
+
182
232
struct S;
183
233
impl core::ops::Deref for S {
184
234
type Target = S;
0 commit comments