@@ -2,14 +2,18 @@ use std::collections::BTreeSet;
2
2
3
3
use ast:: make;
4
4
use either:: Either ;
5
- use hir:: { db:: HirDatabase , sym, FileRange , PathResolution , Semantics , TypeInfo } ;
5
+ use hir:: {
6
+ db:: { ExpandDatabase , HirDatabase } ,
7
+ sym, FileRange , PathResolution , Semantics , TypeInfo ,
8
+ } ;
6
9
use ide_db:: {
10
+ base_db:: CrateId ,
7
11
defs:: Definition ,
8
12
imports:: insert_use:: remove_path_if_in_use_stmt,
9
13
path_transform:: PathTransform ,
10
14
search:: { FileReference , FileReferenceNode , SearchScope } ,
11
15
source_change:: SourceChangeBuilder ,
12
- syntax_helpers:: { insert_whitespace_into_node :: insert_ws_into , node_ext:: expr_as_name_ref} ,
16
+ syntax_helpers:: { node_ext:: expr_as_name_ref, prettify_macro_expansion } ,
13
17
EditionedFileId , RootDatabase ,
14
18
} ;
15
19
use itertools:: { izip, Itertools } ;
@@ -102,12 +106,13 @@ pub(crate) fn inline_into_callers(acc: &mut Assists, ctx: &AssistContext<'_>) ->
102
106
let mut remove_def = true ;
103
107
let mut inline_refs_for_file = |file_id, refs : Vec < FileReference > | {
104
108
builder. edit_file ( file_id) ;
109
+ let call_krate = ctx. sema . file_to_module_def ( file_id) . map ( |it| it. krate ( ) ) ;
105
110
let count = refs. len ( ) ;
106
111
// The collects are required as we are otherwise iterating while mutating 🙅♀️🙅♂️
107
112
let ( name_refs, name_refs_use) = split_refs_and_uses ( builder, refs, Some ) ;
108
113
let call_infos: Vec < _ > = name_refs
109
114
. into_iter ( )
110
- . filter_map ( CallInfo :: from_name_ref)
115
+ . filter_map ( |it| CallInfo :: from_name_ref ( it , call_krate? . into ( ) ) )
111
116
// FIXME: do not handle callsites in macros' parameters, because
112
117
// directly inlining into macros may cause errors.
113
118
. filter ( |call_info| !ctx. sema . hir_file_for ( call_info. node . syntax ( ) ) . is_macro ( ) )
@@ -185,7 +190,10 @@ pub(super) fn split_refs_and_uses<T: ast::AstNode>(
185
190
// ```
186
191
pub ( crate ) fn inline_call ( acc : & mut Assists , ctx : & AssistContext < ' _ > ) -> Option < ( ) > {
187
192
let name_ref: ast:: NameRef = ctx. find_node_at_offset ( ) ?;
188
- let call_info = CallInfo :: from_name_ref ( name_ref. clone ( ) ) ?;
193
+ let call_info = CallInfo :: from_name_ref (
194
+ name_ref. clone ( ) ,
195
+ ctx. sema . file_to_module_def ( ctx. file_id ( ) ) ?. krate ( ) . into ( ) ,
196
+ ) ?;
189
197
let ( function, label) = match & call_info. node {
190
198
ast:: CallableExpr :: Call ( call) => {
191
199
let path = match call. expr ( ) ? {
@@ -243,10 +251,11 @@ struct CallInfo {
243
251
node : ast:: CallableExpr ,
244
252
arguments : Vec < ast:: Expr > ,
245
253
generic_arg_list : Option < ast:: GenericArgList > ,
254
+ krate : CrateId ,
246
255
}
247
256
248
257
impl CallInfo {
249
- fn from_name_ref ( name_ref : ast:: NameRef ) -> Option < CallInfo > {
258
+ fn from_name_ref ( name_ref : ast:: NameRef , krate : CrateId ) -> Option < CallInfo > {
250
259
let parent = name_ref. syntax ( ) . parent ( ) ?;
251
260
if let Some ( call) = ast:: MethodCallExpr :: cast ( parent. clone ( ) ) {
252
261
let receiver = call. receiver ( ) ?;
@@ -256,6 +265,7 @@ impl CallInfo {
256
265
generic_arg_list : call. generic_arg_list ( ) ,
257
266
node : ast:: CallableExpr :: MethodCall ( call) ,
258
267
arguments,
268
+ krate,
259
269
} )
260
270
} else if let Some ( segment) = ast:: PathSegment :: cast ( parent) {
261
271
let path = segment. syntax ( ) . parent ( ) . and_then ( ast:: Path :: cast) ?;
@@ -266,6 +276,7 @@ impl CallInfo {
266
276
arguments : call. arg_list ( ) ?. args ( ) . collect ( ) ,
267
277
node : ast:: CallableExpr :: Call ( call) ,
268
278
generic_arg_list : segment. generic_arg_list ( ) ,
279
+ krate,
269
280
} )
270
281
} else {
271
282
None
@@ -307,11 +318,15 @@ fn inline(
307
318
function : hir:: Function ,
308
319
fn_body : & ast:: BlockExpr ,
309
320
params : & [ ( ast:: Pat , Option < ast:: Type > , hir:: Param ) ] ,
310
- CallInfo { node, arguments, generic_arg_list } : & CallInfo ,
321
+ CallInfo { node, arguments, generic_arg_list, krate } : & CallInfo ,
311
322
) -> ast:: Expr {
312
- let mut body = if sema. hir_file_for ( fn_body. syntax ( ) ) . is_macro ( ) {
323
+ let file_id = sema. hir_file_for ( fn_body. syntax ( ) ) ;
324
+ let mut body = if let Some ( macro_file) = file_id. macro_file ( ) {
313
325
cov_mark:: hit!( inline_call_defined_in_macro) ;
314
- if let Some ( body) = ast:: BlockExpr :: cast ( insert_ws_into ( fn_body. syntax ( ) . clone ( ) ) ) {
326
+ let span_map = sema. db . expansion_span_map ( macro_file) ;
327
+ let body_prettified =
328
+ prettify_macro_expansion ( sema. db , fn_body. syntax ( ) . clone ( ) , & span_map, * krate) ;
329
+ if let Some ( body) = ast:: BlockExpr :: cast ( body_prettified) {
315
330
body
316
331
} else {
317
332
fn_body. clone_for_update ( )
@@ -420,8 +435,16 @@ fn inline(
420
435
421
436
let mut insert_let_stmt = || {
422
437
let param_ty = param_ty. clone ( ) . map ( |param_ty| {
423
- if sema. hir_file_for ( param_ty. syntax ( ) ) . is_macro ( ) {
424
- ast:: Type :: cast ( insert_ws_into ( param_ty. syntax ( ) . clone ( ) ) ) . unwrap_or ( param_ty)
438
+ let file_id = sema. hir_file_for ( param_ty. syntax ( ) ) ;
439
+ if let Some ( macro_file) = file_id. macro_file ( ) {
440
+ let span_map = sema. db . expansion_span_map ( macro_file) ;
441
+ let param_ty_prettified = prettify_macro_expansion (
442
+ sema. db ,
443
+ param_ty. syntax ( ) . clone ( ) ,
444
+ & span_map,
445
+ * krate,
446
+ ) ;
447
+ ast:: Type :: cast ( param_ty_prettified) . unwrap_or ( param_ty)
425
448
} else {
426
449
param_ty
427
450
}
0 commit comments