1
+ use std:: collections:: VecDeque ;
1
2
use wasm_bindgen:: prelude:: * ;
2
3
use rslint_parser:: { ast:: { ArrowExpr , CallExpr , Expr , ExprOrBlock , FnDecl , FnExpr , ReturnStmt } , parse_text, AstNode , SyntaxNode , TextSize } ;
3
4
@@ -25,15 +26,15 @@ fn is_block(body: &ExprOrBlock) -> bool {
25
26
}
26
27
}
27
28
28
- fn fn_start_insertion ( body : & ExprOrBlock ) -> Vec < Insertion > {
29
- let mut ret = Vec :: new ( ) ;
29
+ fn fn_start_insertion ( body : & ExprOrBlock ) -> VecDeque < Insertion > {
30
+ let mut ret = VecDeque :: new ( ) ;
30
31
let mut offset = body. syntax ( ) . text_range ( ) . start ( ) ;
31
32
if !is_block ( body) {
32
- ret. push ( Insertion :: new ( offset, "{" ) ) ;
33
+ ret. push_back ( Insertion :: new ( offset, "{" ) ) ;
33
34
} else {
34
35
offset = offset. checked_add ( 1 . into ( ) ) . unwrap ( ) ;
35
36
}
36
- ret. push ( Insertion :: new ( offset, r#"
37
+ ret. push_back ( Insertion :: new ( offset, r#"
37
38
const _syntheticPromise = Symbol.for('@@mongosh.syntheticPromise');
38
39
39
40
function _markSyntheticPromise(p) {
@@ -53,22 +54,22 @@ fn fn_start_insertion(body: &ExprOrBlock) -> Vec<Insertion> {
53
54
"#
54
55
) ) ;
55
56
if !is_block ( body) {
56
- ret. push ( Insertion :: new (
57
+ ret. push_back ( Insertion :: new (
57
58
offset,
58
59
"return ("
59
60
) ) ;
60
61
}
61
62
ret
62
63
}
63
- fn fn_end_insertion ( body : & ExprOrBlock ) -> Vec < Insertion > {
64
- let mut ret = Vec :: new ( ) ;
64
+ fn fn_end_insertion ( body : & ExprOrBlock ) -> VecDeque < Insertion > {
65
+ let mut ret = VecDeque :: new ( ) ;
65
66
let mut offset = body. syntax ( ) . text_range ( ) . end ( ) ;
66
67
if is_block ( body) {
67
68
offset = offset. checked_sub ( 1 . into ( ) ) . unwrap ( ) ;
68
69
} else {
69
- ret. push ( Insertion :: new ( offset, ");" ) ) ;
70
+ ret. push_back ( Insertion :: new ( offset, ");" ) ) ;
70
71
}
71
- ret. push ( Insertion :: new (
72
+ ret. push_back ( Insertion :: new (
72
73
offset,
73
74
r#"
74
75
} catch (err) {
@@ -98,17 +99,18 @@ fn fn_end_insertion(body: &ExprOrBlock) -> Vec<Insertion> {
98
99
"#
99
100
) ) ;
100
101
if !is_block ( body) {
101
- ret. push ( Insertion :: new ( offset, "}" ) ) ;
102
+ ret. push_back ( Insertion :: new ( offset, "}" ) ) ;
102
103
}
103
104
ret
104
105
}
105
106
106
- fn collect_insertions ( node : & SyntaxNode , has_function_parent : bool ) -> Vec < Insertion > {
107
+ fn collect_insertions ( node : & SyntaxNode , nesting_depth : u32 ) -> VecDeque < Insertion > {
107
108
let is_function_node = FnExpr :: can_cast ( node. kind ( ) ) || FnDecl :: can_cast ( node. kind ( ) ) || ArrowExpr :: can_cast ( node. kind ( ) ) ;
108
- let mut insertions = Vec :: new ( ) ;
109
+ let has_function_parent = nesting_depth > 0 ;
110
+ let mut insertions = VecDeque :: new ( ) ;
109
111
for child in node. children ( ) {
110
112
let range = child. text_range ( ) ;
111
- let child_insertions = & mut collect_insertions ( & child, has_function_parent || is_function_node) ;
113
+ let child_insertions = & mut collect_insertions ( & child, nesting_depth + if is_function_node { 1 } else { 0 } ) ;
112
114
if FnDecl :: can_cast ( child. kind ( ) ) {
113
115
let as_fn = FnDecl :: cast ( child) . unwrap ( ) ;
114
116
if as_fn. async_token ( ) . is_none ( ) {
@@ -129,9 +131,9 @@ fn collect_insertions(node: &SyntaxNode, has_function_parent: bool) -> Vec<Inser
129
131
let mut is_dot_call_expression = false ;
130
132
if has_function_parent {
131
133
if is_returned_expression {
132
- insertions. push ( Insertion :: new ( range. start ( ) , "(_synchronousReturnValue = " ) ) ;
134
+ insertions. push_back ( Insertion :: new ( range. start ( ) , "(_synchronousReturnValue = " ) ) ;
133
135
}
134
- insertions. push ( Insertion :: new ( range. start ( ) , "(_ex = " ) ) ;
136
+ insertions. push_back ( Insertion :: new ( range. start ( ) , "(_ex = " ) ) ;
135
137
}
136
138
137
139
match as_expr {
@@ -154,7 +156,7 @@ fn collect_insertions(node: &SyntaxNode, has_function_parent: bool) -> Vec<Inser
154
156
Expr :: DotExpr ( _) => {
155
157
if is_called_expression {
156
158
is_dot_call_expression = true ;
157
- insertions. pop ( ) ;
159
+ insertions. pop_back ( ) ;
158
160
}
159
161
insertions. append ( child_insertions) ;
160
162
}
@@ -164,10 +166,10 @@ fn collect_insertions(node: &SyntaxNode, has_function_parent: bool) -> Vec<Inser
164
166
}
165
167
if has_function_parent {
166
168
if !is_dot_call_expression {
167
- insertions. push ( Insertion :: new ( range. end ( ) , ", _isp(_ex) ? await _ex : _ex)" ) ) ;
169
+ insertions. push_back ( Insertion :: new ( range. end ( ) , ", _isp(_ex) ? await _ex : _ex)" ) ) ;
168
170
}
169
171
if is_returned_expression {
170
- insertions. push ( Insertion :: new (
172
+ insertions. push_back ( Insertion :: new (
171
173
range. end ( ) ,
172
174
", _functionState === 'async' ? _synchronousReturnValue : null)"
173
175
) ) ;
@@ -182,13 +184,13 @@ fn collect_insertions(node: &SyntaxNode, has_function_parent: bool) -> Vec<Inser
182
184
#[ wasm_bindgen]
183
185
pub fn async_rewrite ( input : String , with_debug_tags : bool ) -> String {
184
186
let parsed = parse_text ( input. as_str ( ) , 0 ) ;
185
- let mut insertions = collect_insertions ( & parsed. syntax ( ) , false ) ;
187
+ let mut insertions = collect_insertions ( & parsed. syntax ( ) , 0 ) ;
186
188
let mut i = 0 ;
187
189
for insertion in & mut insertions {
188
190
i += 1 ;
189
191
insertion. original_ordering = Some ( i) ;
190
192
}
191
- insertions. sort_by ( |a, b| a. offset . cmp ( & b. offset ) ) ;
193
+ insertions. make_contiguous ( ) . sort_by ( |a, b| a. offset . cmp ( & b. offset ) ) ;
192
194
193
195
let mut result = input. to_string ( ) ;
194
196
let mut debug_tag = "" . to_string ( ) ;
@@ -197,7 +199,8 @@ pub fn async_rewrite(input: String, with_debug_tags: bool) -> String {
197
199
if with_debug_tags {
198
200
debug_tag = [
199
201
"/*i" , insertion. original_ordering . unwrap ( ) . to_string ( ) . as_str ( ) , "@" ,
200
- u32:: from ( insertion. offset ) . to_string ( ) . as_str ( ) , "*/"
202
+ u32:: from ( insertion. offset ) . to_string ( ) . as_str ( ) ,
203
+ if insertion. text . contains ( "/*" ) { "" } else { "*/" }
201
204
] . concat ( ) ;
202
205
}
203
206
result = [ before, debug_tag. as_str ( ) , insertion. text , debug_tag. as_str ( ) , after] . concat ( ) ;
0 commit comments