1
1
use either:: Either ;
2
2
use ide_db:: syntax_helpers:: node_ext:: walk_ty;
3
- use syntax:: ast:: { self , edit:: IndentLevel , make, AstNode , HasGenericParams , HasName } ;
3
+ use syntax:: {
4
+ ast:: { self , edit:: IndentLevel , make, AstNode , HasGenericParams , HasName } ,
5
+ ted,
6
+ } ;
4
7
5
8
use crate :: { AssistContext , AssistId , AssistKind , Assists } ;
6
9
@@ -34,14 +37,16 @@ pub(crate) fn extract_type_alias(acc: &mut Assists, ctx: &AssistContext<'_>) ->
34
37
|| item. syntax ( ) ,
35
38
|impl_| impl_. as_ref ( ) . either ( AstNode :: syntax, AstNode :: syntax) ,
36
39
) ;
37
- let insert_pos = node. text_range ( ) . start ( ) ;
38
40
let target = ty. syntax ( ) . text_range ( ) ;
39
41
40
42
acc. add (
41
43
AssistId ( "extract_type_alias" , AssistKind :: RefactorExtract ) ,
42
44
"Extract type as type alias" ,
43
45
target,
44
- |builder| {
46
+ |edit| {
47
+ let node = edit. make_syntax_mut ( node. clone ( ) ) ;
48
+ let target_ty = edit. make_mut ( ty. clone ( ) ) ;
49
+
45
50
let mut known_generics = match item. generic_param_list ( ) {
46
51
Some ( it) => it. generic_params ( ) . collect ( ) ,
47
52
None => Vec :: new ( ) ,
@@ -56,27 +61,29 @@ pub(crate) fn extract_type_alias(acc: &mut Assists, ctx: &AssistContext<'_>) ->
56
61
let generic_params =
57
62
generics. map ( |it| make:: generic_param_list ( it. into_iter ( ) . cloned ( ) ) ) ;
58
63
64
+ // Replace original type with the alias
59
65
let ty_args = generic_params
60
66
. as_ref ( )
61
67
. map_or ( String :: new ( ) , |it| it. to_generic_args ( ) . to_string ( ) ) ;
62
- let replacement = format ! ( "Type{ty_args}" ) ;
63
- builder. replace ( target, replacement) ;
64
-
65
- let indent = IndentLevel :: from_node ( node) ;
66
- let generic_params = generic_params. map_or ( String :: new ( ) , |it| it. to_string ( ) ) ;
67
- match ctx. config . snippet_cap {
68
- Some ( cap) => {
69
- builder. insert_snippet (
70
- cap,
71
- insert_pos,
72
- format ! ( "type $0Type{generic_params} = {ty};\n \n {indent}" ) ,
73
- ) ;
74
- }
75
- None => {
76
- builder. insert (
77
- insert_pos,
78
- format ! ( "type Type{generic_params} = {ty};\n \n {indent}" ) ,
79
- ) ;
68
+ // FIXME: replace with a `ast::make` constructor
69
+ let new_ty = make:: ty ( & format ! ( "Type{ty_args}" ) ) . clone_for_update ( ) ;
70
+ ted:: replace ( target_ty. syntax ( ) , new_ty. syntax ( ) ) ;
71
+
72
+ // Insert new alias
73
+ let indent = IndentLevel :: from_node ( & node) ;
74
+ let ty_alias = make:: ty_alias ( "Type" , generic_params, None , None , Some ( ( ty, None ) ) )
75
+ . clone_for_update ( ) ;
76
+ ted:: insert_all (
77
+ ted:: Position :: before ( node) ,
78
+ vec ! [
79
+ ty_alias. syntax( ) . clone( ) . into( ) ,
80
+ make:: tokens:: whitespace( & format!( "\n \n {indent}" ) ) . into( ) ,
81
+ ] ,
82
+ ) ;
83
+
84
+ if let Some ( cap) = ctx. config . snippet_cap {
85
+ if let Some ( name) = ty_alias. name ( ) {
86
+ edit. add_tabstop_before ( cap, name) ;
80
87
}
81
88
}
82
89
} ,
0 commit comments