@@ -6,7 +6,7 @@ use mbe::{SyntheticToken, SyntheticTokenId, TokenMap};
6
6
use rustc_hash:: FxHashMap ;
7
7
use syntax:: {
8
8
ast:: { self , AstNode } ,
9
- match_ast, SyntaxKind , SyntaxNode , TextRange ,
9
+ match_ast, SyntaxElement , SyntaxKind , SyntaxNode , TextRange ,
10
10
} ;
11
11
use tt:: Subtree ;
12
12
@@ -15,8 +15,8 @@ use tt::Subtree;
15
15
/// reverse those changes afterwards, and a token map.
16
16
#[ derive( Debug ) ]
17
17
pub ( crate ) struct SyntaxFixups {
18
- pub ( crate ) append : FxHashMap < SyntaxNode , Vec < SyntheticToken > > ,
19
- pub ( crate ) replace : FxHashMap < SyntaxNode , Vec < SyntheticToken > > ,
18
+ pub ( crate ) append : FxHashMap < SyntaxElement , Vec < SyntheticToken > > ,
19
+ pub ( crate ) replace : FxHashMap < SyntaxElement , Vec < SyntheticToken > > ,
20
20
pub ( crate ) undo_info : SyntaxFixupUndoInfo ,
21
21
pub ( crate ) token_map : TokenMap ,
22
22
pub ( crate ) next_id : u32 ,
@@ -31,8 +31,8 @@ pub struct SyntaxFixupUndoInfo {
31
31
const EMPTY_ID : SyntheticTokenId = SyntheticTokenId ( !0 ) ;
32
32
33
33
pub ( crate ) fn fixup_syntax ( node : & SyntaxNode ) -> SyntaxFixups {
34
- let mut append = FxHashMap :: default ( ) ;
35
- let mut replace = FxHashMap :: default ( ) ;
34
+ let mut append = FxHashMap :: < SyntaxElement , _ > :: default ( ) ;
35
+ let mut replace = FxHashMap :: < SyntaxElement , _ > :: default ( ) ;
36
36
let mut preorder = node. preorder ( ) ;
37
37
let mut original = Vec :: new ( ) ;
38
38
let mut token_map = TokenMap :: default ( ) ;
@@ -63,7 +63,7 @@ pub(crate) fn fixup_syntax(node: &SyntaxNode) -> SyntaxFixups {
63
63
range : node. text_range ( ) ,
64
64
id : SyntheticTokenId ( idx) ,
65
65
} ;
66
- replace. insert ( node. clone ( ) , vec ! [ replacement] ) ;
66
+ replace. insert ( node. clone ( ) . into ( ) , vec ! [ replacement] ) ;
67
67
preorder. skip_subtree ( ) ;
68
68
continue ;
69
69
}
@@ -75,7 +75,7 @@ pub(crate) fn fixup_syntax(node: &SyntaxNode) -> SyntaxFixups {
75
75
ast:: FieldExpr ( it) => {
76
76
if it. name_ref( ) . is_none( ) {
77
77
// incomplete field access: some_expr.|
78
- append. insert( node. clone( ) , vec![
78
+ append. insert( node. clone( ) . into ( ) , vec![
79
79
SyntheticToken {
80
80
kind: SyntaxKind :: IDENT ,
81
81
text: "__ra_fixup" . into( ) ,
@@ -87,7 +87,7 @@ pub(crate) fn fixup_syntax(node: &SyntaxNode) -> SyntaxFixups {
87
87
} ,
88
88
ast:: ExprStmt ( it) => {
89
89
if it. semicolon_token( ) . is_none( ) {
90
- append. insert( node. clone( ) , vec![
90
+ append. insert( node. clone( ) . into ( ) , vec![
91
91
SyntheticToken {
92
92
kind: SyntaxKind :: SEMICOLON ,
93
93
text: ";" . into( ) ,
@@ -99,7 +99,7 @@ pub(crate) fn fixup_syntax(node: &SyntaxNode) -> SyntaxFixups {
99
99
} ,
100
100
ast:: LetStmt ( it) => {
101
101
if it. semicolon_token( ) . is_none( ) {
102
- append. insert( node. clone( ) , vec![
102
+ append. insert( node. clone( ) . into ( ) , vec![
103
103
SyntheticToken {
104
104
kind: SyntaxKind :: SEMICOLON ,
105
105
text: ";" . into( ) ,
@@ -109,6 +109,41 @@ pub(crate) fn fixup_syntax(node: &SyntaxNode) -> SyntaxFixups {
109
109
] ) ;
110
110
}
111
111
} ,
112
+ ast:: IfExpr ( it) => {
113
+ if it. condition( ) . is_none( ) {
114
+ // insert placeholder token after the if token
115
+ let if_token = match it. if_token( ) {
116
+ Some ( t) => t,
117
+ None => continue ,
118
+ } ;
119
+ append. insert( if_token. into( ) , vec![
120
+ SyntheticToken {
121
+ kind: SyntaxKind :: IDENT ,
122
+ text: "__ra_fixup" . into( ) ,
123
+ range: end_range,
124
+ id: EMPTY_ID ,
125
+ } ,
126
+ ] ) ;
127
+ }
128
+ if it. then_branch( ) . is_none( ) {
129
+ append. insert( node. clone( ) . into( ) , vec![
130
+ SyntheticToken {
131
+ kind: SyntaxKind :: L_CURLY ,
132
+ text: "{" . into( ) ,
133
+ range: end_range,
134
+ id: EMPTY_ID ,
135
+ } ,
136
+ SyntheticToken {
137
+ kind: SyntaxKind :: R_CURLY ,
138
+ text: "}" . into( ) ,
139
+ range: end_range,
140
+ id: EMPTY_ID ,
141
+ } ,
142
+ ] ) ;
143
+ }
144
+ } ,
145
+ // FIXME: foo::
146
+ // FIXME: for, loop, match etc.
112
147
_ => ( ) ,
113
148
}
114
149
}
@@ -144,7 +179,10 @@ pub(crate) fn reverse_fixups(
144
179
token_map. synthetic_token_id ( leaf. id ( ) ) . is_none ( )
145
180
|| token_map. synthetic_token_id ( leaf. id ( ) ) != Some ( EMPTY_ID )
146
181
}
147
- _ => true ,
182
+ tt:: TokenTree :: Subtree ( st) => st. delimiter . map_or ( true , |d| {
183
+ token_map. synthetic_token_id ( d. id ) . is_none ( )
184
+ || token_map. synthetic_token_id ( d. id ) != Some ( EMPTY_ID )
185
+ } ) ,
148
186
} ) ;
149
187
tt. token_trees . iter_mut ( ) . for_each ( |tt| match tt {
150
188
tt:: TokenTree :: Subtree ( tt) => reverse_fixups ( tt, token_map, undo_info) ,
@@ -295,6 +333,49 @@ fn foo() {
295
333
"# ,
296
334
expect ! [ [ r#"
297
335
fn foo () {__ra_fixup ;}
336
+ "# ] ] ,
337
+ )
338
+ }
339
+
340
+ #[ test]
341
+ fn fixup_if_1 ( ) {
342
+ check (
343
+ r#"
344
+ fn foo() {
345
+ if a
346
+ }
347
+ "# ,
348
+ expect ! [ [ r#"
349
+ fn foo () {if a {}}
350
+ "# ] ] ,
351
+ )
352
+ }
353
+
354
+ #[ test]
355
+ fn fixup_if_2 ( ) {
356
+ check (
357
+ r#"
358
+ fn foo() {
359
+ if
360
+ }
361
+ "# ,
362
+ expect ! [ [ r#"
363
+ fn foo () {if __ra_fixup {}}
364
+ "# ] ] ,
365
+ )
366
+ }
367
+
368
+ #[ test]
369
+ fn fixup_if_3 ( ) {
370
+ check (
371
+ r#"
372
+ fn foo() {
373
+ if {}
374
+ }
375
+ "# ,
376
+ // the {} gets parsed as the condition, I think?
377
+ expect ! [ [ r#"
378
+ fn foo () {if {} {}}
298
379
"# ] ] ,
299
380
)
300
381
}
0 commit comments