aboutsummaryrefslogtreecommitdiff
path: root/crates/ide/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ide/src')
-rw-r--r--crates/ide/src/display/navigation_target.rs12
-rw-r--r--crates/ide/src/fixture.rs16
-rw-r--r--crates/ide/src/goto_definition.rs13
-rw-r--r--crates/ide/src/join_lines.rs41
-rw-r--r--crates/ide/src/parent_module.rs71
-rw-r--r--crates/ide/src/references.rs23
-rw-r--r--crates/ide/src/syntax_highlighting/tests.rs51
-rw-r--r--crates/ide/src/syntax_tree.rs366
8 files changed, 316 insertions, 277 deletions
diff --git a/crates/ide/src/display/navigation_target.rs b/crates/ide/src/display/navigation_target.rs
index 23d885218..198243466 100644
--- a/crates/ide/src/display/navigation_target.rs
+++ b/crates/ide/src/display/navigation_target.rs
@@ -85,12 +85,16 @@ impl NavigationTarget {
85 let name = module.name(db).map(|it| it.to_string().into()).unwrap_or_default(); 85 let name = module.name(db).map(|it| it.to_string().into()).unwrap_or_default();
86 if let Some(src) = module.declaration_source(db) { 86 if let Some(src) = module.declaration_source(db) {
87 let node = src.as_ref().map(|it| it.syntax()); 87 let node = src.as_ref().map(|it| it.syntax());
88 let frange = node.original_file_range(db); 88 let full_range = node.original_file_range(db);
89 let focus_range = src
90 .value
91 .name()
92 .map(|name| src.with_value(name.syntax()).original_file_range(db).range);
89 let mut res = NavigationTarget::from_syntax( 93 let mut res = NavigationTarget::from_syntax(
90 frange.file_id, 94 full_range.file_id,
91 name, 95 name,
92 None, 96 focus_range,
93 frange.range, 97 full_range.range,
94 SymbolKind::Module, 98 SymbolKind::Module,
95 ); 99 );
96 res.docs = module.attrs(db).docs(); 100 res.docs = module.attrs(db).docs();
diff --git a/crates/ide/src/fixture.rs b/crates/ide/src/fixture.rs
index cc8218885..cc6641ba1 100644
--- a/crates/ide/src/fixture.rs
+++ b/crates/ide/src/fixture.rs
@@ -1,5 +1,6 @@
1//! Utilities for creating `Analysis` instances for tests. 1//! Utilities for creating `Analysis` instances for tests.
2use ide_db::base_db::fixture::ChangeFixture; 2use ide_db::base_db::fixture::ChangeFixture;
3use syntax::{TextRange, TextSize};
3use test_utils::{extract_annotations, RangeOrOffset}; 4use test_utils::{extract_annotations, RangeOrOffset};
4 5
5use crate::{Analysis, AnalysisHost, FileId, FilePosition, FileRange}; 6use crate::{Analysis, AnalysisHost, FileId, FilePosition, FileRange};
@@ -68,3 +69,18 @@ pub(crate) fn annotations(ra_fixture: &str) -> (Analysis, FilePosition, Vec<(Fil
68 .collect(); 69 .collect();
69 (host.analysis(), FilePosition { file_id, offset }, annotations) 70 (host.analysis(), FilePosition { file_id, offset }, annotations)
70} 71}
72
73pub(crate) fn nav_target_annotation(ra_fixture: &str) -> (Analysis, FilePosition, FileRange) {
74 let (analysis, position, mut annotations) = annotations(ra_fixture);
75 let (mut expected, data) = annotations.pop().unwrap();
76 assert!(annotations.is_empty());
77 match data.as_str() {
78 "" => (),
79 "file" => {
80 expected.range =
81 TextRange::up_to(TextSize::of(&*analysis.file_text(expected.file_id).unwrap()))
82 }
83 data => panic!("bad data: {}", data),
84 }
85 (analysis, position, expected)
86}
diff --git a/crates/ide/src/goto_definition.rs b/crates/ide/src/goto_definition.rs
index 1a997fa40..e86ae2a18 100644
--- a/crates/ide/src/goto_definition.rs
+++ b/crates/ide/src/goto_definition.rs
@@ -131,22 +131,11 @@ pub(crate) fn reference_definition(
131#[cfg(test)] 131#[cfg(test)]
132mod tests { 132mod tests {
133 use ide_db::base_db::FileRange; 133 use ide_db::base_db::FileRange;
134 use syntax::{TextRange, TextSize};
135 134
136 use crate::fixture; 135 use crate::fixture;
137 136
138 fn check(ra_fixture: &str) { 137 fn check(ra_fixture: &str) {
139 let (analysis, position, mut annotations) = fixture::annotations(ra_fixture); 138 let (analysis, position, expected) = fixture::nav_target_annotation(ra_fixture);
140 let (mut expected, data) = annotations.pop().unwrap();
141 match data.as_str() {
142 "" => (),
143 "file" => {
144 expected.range =
145 TextRange::up_to(TextSize::of(&*analysis.file_text(expected.file_id).unwrap()))
146 }
147 data => panic!("bad data: {}", data),
148 }
149
150 let mut navs = 139 let mut navs =
151 analysis.goto_definition(position).unwrap().expect("no definition found").info; 140 analysis.goto_definition(position).unwrap().expect("no definition found").info;
152 if navs.len() == 0 { 141 if navs.len() == 0 {
diff --git a/crates/ide/src/join_lines.rs b/crates/ide/src/join_lines.rs
index 631bde0f1..e3f3985d1 100644
--- a/crates/ide/src/join_lines.rs
+++ b/crates/ide/src/join_lines.rs
@@ -270,27 +270,28 @@ fn foo() {
270 270
271 #[test] 271 #[test]
272 fn test_join_lines_diverging_block() { 272 fn test_join_lines_diverging_block() {
273 let before = r" 273 check_join_lines(
274 fn foo() { 274 r"
275 loop { 275fn foo() {
276 match x { 276 loop {
277 92 => $0{ 277 match x {
278 continue; 278 92 => $0{
279 } 279 continue;
280 }
281 }
282 }
283 ";
284 let after = r"
285 fn foo() {
286 loop {
287 match x {
288 92 => $0continue,
289 }
290 }
291 } 280 }
292 "; 281 }
293 check_join_lines(before, after); 282 }
283}
284 ",
285 r"
286fn foo() {
287 loop {
288 match x {
289 92 => $0continue,
290 }
291 }
292}
293 ",
294 );
294 } 295 }
295 296
296 #[test] 297 #[test]
diff --git a/crates/ide/src/parent_module.rs b/crates/ide/src/parent_module.rs
index d343638fb..ddbaf22b7 100644
--- a/crates/ide/src/parent_module.rs
+++ b/crates/ide/src/parent_module.rs
@@ -63,57 +63,62 @@ pub(crate) fn crate_for(db: &RootDatabase, file_id: FileId) -> Vec<CrateId> {
63 63
64#[cfg(test)] 64#[cfg(test)]
65mod tests { 65mod tests {
66 use ide_db::base_db::FileRange;
66 use test_utils::mark; 67 use test_utils::mark;
67 68
68 use crate::fixture::{self}; 69 use crate::fixture;
70
71 fn check(ra_fixture: &str) {
72 let (analysis, position, expected) = fixture::nav_target_annotation(ra_fixture);
73 let mut navs = analysis.parent_module(position).unwrap();
74 assert_eq!(navs.len(), 1);
75 let nav = navs.pop().unwrap();
76 assert_eq!(expected, FileRange { file_id: nav.file_id, range: nav.focus_or_full_range() });
77 }
69 78
70 #[test] 79 #[test]
71 fn test_resolve_parent_module() { 80 fn test_resolve_parent_module() {
72 let (analysis, pos) = fixture::position( 81 check(
73 " 82 r#"
74 //- /lib.rs 83//- /lib.rs
75 mod foo; 84mod foo;
76 //- /foo.rs 85 //^^^
77 $0// empty 86
78 ", 87//- /foo.rs
88$0// empty
89"#,
79 ); 90 );
80 let nav = analysis.parent_module(pos).unwrap().pop().unwrap();
81 nav.assert_match("foo Module FileId(0) 0..8");
82 } 91 }
83 92
84 #[test] 93 #[test]
85 fn test_resolve_parent_module_on_module_decl() { 94 fn test_resolve_parent_module_on_module_decl() {
86 mark::check!(test_resolve_parent_module_on_module_decl); 95 mark::check!(test_resolve_parent_module_on_module_decl);
87 let (analysis, pos) = fixture::position( 96 check(
88 " 97 r#"
89 //- /lib.rs 98//- /lib.rs
90 mod foo; 99mod foo;
91 100 //^^^
92 //- /foo.rs 101//- /foo.rs
93 mod $0bar; 102mod $0bar;
94 103
95 //- /foo/bar.rs 104//- /foo/bar.rs
96 // empty 105// empty
97 ", 106"#,
98 ); 107 );
99 let nav = analysis.parent_module(pos).unwrap().pop().unwrap();
100 nav.assert_match("foo Module FileId(0) 0..8");
101 } 108 }
102 109
103 #[test] 110 #[test]
104 fn test_resolve_parent_module_for_inline() { 111 fn test_resolve_parent_module_for_inline() {
105 let (analysis, pos) = fixture::position( 112 check(
106 " 113 r#"
107 //- /lib.rs 114//- /lib.rs
108 mod foo { 115mod foo {
109 mod bar { 116 mod bar {
110 mod baz { $0 } 117 mod baz { $0 }
111 } 118 } //^^^
112 } 119}
113 ", 120"#,
114 ); 121 );
115 let nav = analysis.parent_module(pos).unwrap().pop().unwrap();
116 nav.assert_match("baz Module FileId(0) 32..44");
117 } 122 }
118 123
119 #[test] 124 #[test]
diff --git a/crates/ide/src/references.rs b/crates/ide/src/references.rs
index 40d9487eb..6999dacee 100644
--- a/crates/ide/src/references.rs
+++ b/crates/ide/src/references.rs
@@ -1114,4 +1114,27 @@ trait Foo {
1114 "#]], 1114 "#]],
1115 ); 1115 );
1116 } 1116 }
1117
1118 #[test]
1119 fn test_self_variant_with_payload() {
1120 check(
1121 r#"
1122enum Foo { Bar() }
1123
1124impl Foo {
1125 fn foo(self) {
1126 match self {
1127 Self::Bar$0() => (),
1128 }
1129 }
1130}
1131
1132"#,
1133 expect![[r#"
1134 Bar Variant FileId(0) 11..16 11..14 Other
1135
1136 FileId(0) 89..92 Other
1137 "#]],
1138 );
1139 }
1117} 1140}
diff --git a/crates/ide/src/syntax_highlighting/tests.rs b/crates/ide/src/syntax_highlighting/tests.rs
index 1854da914..9d0cd1af5 100644
--- a/crates/ide/src/syntax_highlighting/tests.rs
+++ b/crates/ide/src/syntax_highlighting/tests.rs
@@ -1,9 +1,8 @@
1use std::fs;
2
3use expect_test::{expect_file, ExpectFile}; 1use expect_test::{expect_file, ExpectFile};
4use test_utils::project_dir; 2use ide_db::SymbolKind;
3use test_utils::{bench, bench_fixture, skip_slow_tests};
5 4
6use crate::{fixture, FileRange, TextRange}; 5use crate::{fixture, FileRange, HlTag, TextRange};
7 6
8#[test] 7#[test]
9fn test_highlighting() { 8fn test_highlighting() {
@@ -228,15 +227,45 @@ fn bar() {
228} 227}
229 228
230#[test] 229#[test]
231fn accidentally_quadratic() { 230fn benchmark_syntax_highlighting_long_struct() {
232 let file = project_dir().join("crates/syntax/test_data/accidentally_quadratic"); 231 if skip_slow_tests() {
233 let src = fs::read_to_string(file).unwrap(); 232 return;
233 }
234 234
235 let (analysis, file_id) = fixture::file(&src); 235 let fixture = bench_fixture::big_struct();
236 let (analysis, file_id) = fixture::file(&fixture);
236 237
237 // let t = std::time::Instant::now(); 238 let hash = {
238 let _ = analysis.highlight(file_id).unwrap(); 239 let _pt = bench("syntax highlighting long struct");
239 // eprintln!("elapsed: {:?}", t.elapsed()); 240 analysis
241 .highlight(file_id)
242 .unwrap()
243 .iter()
244 .filter(|it| it.highlight.tag == HlTag::Symbol(SymbolKind::Struct))
245 .count()
246 };
247 assert_eq!(hash, 2001);
248}
249
250#[test]
251fn benchmark_syntax_highlighting_parser() {
252 if skip_slow_tests() {
253 return;
254 }
255
256 let fixture = bench_fixture::glorious_old_parser();
257 let (analysis, file_id) = fixture::file(&fixture);
258
259 let hash = {
260 let _pt = bench("syntax highlighting parser");
261 analysis
262 .highlight(file_id)
263 .unwrap()
264 .iter()
265 .filter(|it| it.highlight.tag == HlTag::Symbol(SymbolKind::Function))
266 .count()
267 };
268 assert_eq!(hash, 1629);
240} 269}
241 270
242#[test] 271#[test]
diff --git a/crates/ide/src/syntax_tree.rs b/crates/ide/src/syntax_tree.rs
index 4c63d3023..f979ba434 100644
--- a/crates/ide/src/syntax_tree.rs
+++ b/crates/ide/src/syntax_tree.rs
@@ -100,147 +100,137 @@ fn syntax_tree_for_token(node: &SyntaxToken, text_range: TextRange) -> Option<St
100 100
101#[cfg(test)] 101#[cfg(test)]
102mod tests { 102mod tests {
103 use test_utils::assert_eq_text; 103 use expect_test::expect;
104 104
105 use crate::fixture; 105 use crate::fixture;
106 106
107 fn check(ra_fixture: &str, expect: expect_test::Expect) {
108 let (analysis, file_id) = fixture::file(ra_fixture);
109 let syn = analysis.syntax_tree(file_id, None).unwrap();
110 expect.assert_eq(&syn)
111 }
112 fn check_range(ra_fixture: &str, expect: expect_test::Expect) {
113 let (analysis, frange) = fixture::range(ra_fixture);
114 let syn = analysis.syntax_tree(frange.file_id, Some(frange.range)).unwrap();
115 expect.assert_eq(&syn)
116 }
117
107 #[test] 118 #[test]
108 fn test_syntax_tree_without_range() { 119 fn test_syntax_tree_without_range() {
109 // Basic syntax 120 // Basic syntax
110 let (analysis, file_id) = fixture::file(r#"fn foo() {}"#); 121 check(
111 let syn = analysis.syntax_tree(file_id, None).unwrap(); 122 r#"fn foo() {}"#,
112 123 expect![[r#"
113 assert_eq_text!( 124 [email protected]
114 r#" 125 [email protected]
115[email protected] 126 [email protected] "fn"
116 [email protected] 127 [email protected] " "
117 [email protected] "fn" 128 [email protected]
118 [email protected] " " 129 [email protected] "foo"
119 [email protected] 130 [email protected]
120 [email protected] "foo" 131 [email protected] "("
121 [email protected] 132 [email protected] ")"
122 [email protected] "(" 133 [email protected] " "
123 [email protected] ")" 134 [email protected]
124 [email protected] " " 135 [email protected] "{"
125 [email protected] 136 [email protected] "}"
126 [email protected] "{" 137 "#]],
127 [email protected] "}"
128"#
129 .trim(),
130 syn.trim()
131 ); 138 );
132 139
133 let (analysis, file_id) = fixture::file( 140 check(
134 r#" 141 r#"
135fn test() { 142fn test() {
136 assert!(" 143 assert!("
137 fn foo() { 144 fn foo() {
138 } 145 }
139 ", ""); 146 ", "");
140}"# 147}"#,
141 .trim(), 148 expect![[r#"
142 ); 149 [email protected]
143 let syn = analysis.syntax_tree(file_id, None).unwrap(); 150 [email protected]
144 151 [email protected] "fn"
145 assert_eq_text!( 152 [email protected] " "
146 r#" 153 [email protected]
147[email protected] 154 [email protected] "test"
148 [email protected] 155 [email protected]
149 [email protected] "fn" 156 [email protected] "("
150 [email protected] " " 157 [email protected] ")"
151 [email protected] 158 [email protected] " "
152 [email protected] "test" 159 [email protected]
153 [email protected] 160 [email protected] "{"
154 [email protected] "(" 161 [email protected] "\n "
155 [email protected] ")" 162 [email protected]
156 [email protected] " " 163 [email protected]
157 [email protected] 164 [email protected]
158 [email protected] "{" 165 [email protected]
159 [email protected] "\n " 166 [email protected]
160 [email protected] 167 [email protected] "assert"
161 [email protected] 168 [email protected] "!"
162 [email protected] 169 [email protected]
163 [email protected] 170 [email protected] "("
164 [email protected] 171 [email protected] "\"\n fn foo() {\n ..."
165 [email protected] "assert" 172 [email protected] ","
166 [email protected] "!" 173 [email protected] " "
167 [email protected] 174 [email protected] "\"\""
168 [email protected] "(" 175 [email protected] ")"
169 [email protected] "\"\n fn foo() {\n ..." 176 [email protected] ";"
170 [email protected] "," 177 [email protected] "\n"
171 [email protected] " " 178 [email protected] "}"
172 [email protected] "\"\"" 179 "#]],
173 [email protected] ")" 180 )
174 [email protected] ";"
175 [email protected] "\n"
176 [email protected] "}"
177"#
178 .trim(),
179 syn.trim()
180 );
181 } 181 }
182 182
183 #[test] 183 #[test]
184 fn test_syntax_tree_with_range() { 184 fn test_syntax_tree_with_range() {
185 let (analysis, range) = fixture::range(r#"$0fn foo() {}$0"#.trim()); 185 check_range(
186 let syn = analysis.syntax_tree(range.file_id, Some(range.range)).unwrap(); 186 r#"$0fn foo() {}$0"#,
187 187 expect![[r#"
188 assert_eq_text!( 188 [email protected]
189 r#" 189 [email protected] "fn"
190[email protected] 190 [email protected] " "
191 [email protected] "fn" 191 [email protected]
192 [email protected] " " 192 [email protected] "foo"
193 [email protected] 193 [email protected]
194 [email protected] "foo" 194 [email protected] "("
195 [email protected] 195 [email protected] ")"
196 [email protected] "(" 196 [email protected] " "
197 [email protected] ")" 197 [email protected]
198 [email protected] " " 198 [email protected] "{"
199 [email protected] 199 [email protected] "}"
200 [email protected] "{" 200 "#]],
201 [email protected] "}"
202"#
203 .trim(),
204 syn.trim()
205 ); 201 );
206 202
207 let (analysis, range) = fixture::range( 203 check_range(
208 r#"fn test() { 204 r#"
205fn test() {
209 $0assert!(" 206 $0assert!("
210 fn foo() { 207 fn foo() {
211 } 208 }
212 ", "");$0 209 ", "");$0
213}"# 210}"#,
214 .trim(), 211 expect![[r#"
215 ); 212 [email protected]
216 let syn = analysis.syntax_tree(range.file_id, Some(range.range)).unwrap(); 213 [email protected]
217 214 [email protected]
218 assert_eq_text!( 215 [email protected]
219 r#" 216 [email protected]
220[email protected] 217 [email protected] "assert"
221 [email protected] 218 [email protected] "!"
222 [email protected] 219 [email protected]
223 [email protected] 220 [email protected] "("
224 [email protected] 221 [email protected] "\"\n fn foo() {\n ..."
225 [email protected] "assert" 222 [email protected] ","
226 [email protected] "!" 223 [email protected] " "
227 [email protected] 224 [email protected] "\"\""
228 [email protected] "(" 225 [email protected] ")"
229 [email protected] "\"\n fn foo() {\n ..." 226 [email protected] ";"
230 [email protected] "," 227 "#]],
231 [email protected] " "
232 [email protected] "\"\""
233 [email protected] ")"
234 [email protected] ";"
235"#
236 .trim(),
237 syn.trim()
238 ); 228 );
239 } 229 }
240 230
241 #[test] 231 #[test]
242 fn test_syntax_tree_inside_string() { 232 fn test_syntax_tree_inside_string() {
243 let (analysis, range) = fixture::range( 233 check_range(
244 r#"fn test() { 234 r#"fn test() {
245 assert!(" 235 assert!("
246$0fn foo() { 236$0fn foo() {
@@ -248,33 +238,27 @@ $0fn foo() {
248fn bar() { 238fn bar() {
249} 239}
250 ", ""); 240 ", "");
251}"# 241}"#,
252 .trim(), 242 expect![[r#"
253 ); 243 [email protected]
254 let syn = analysis.syntax_tree(range.file_id, Some(range.range)).unwrap(); 244 [email protected]
255 assert_eq_text!( 245 [email protected] "fn"
256 r#" 246 [email protected] " "
257[email protected] 247 [email protected]
258 [email protected] 248 [email protected] "foo"
259 [email protected] "fn" 249 [email protected]
260 [email protected] " " 250 [email protected] "("
261 [email protected] 251 [email protected] ")"
262 [email protected] "foo" 252 [email protected] " "
263 [email protected] 253 [email protected]
264 [email protected] "(" 254 [email protected] "{"
265 [email protected] ")" 255 [email protected] "\n"
266 [email protected] " " 256 [email protected] "}"
267 [email protected] 257 "#]],
268 [email protected] "{"
269 [email protected] "\n"
270 [email protected] "}"
271"#
272 .trim(),
273 syn.trim()
274 ); 258 );
275 259
276 // With a raw string 260 // With a raw string
277 let (analysis, range) = fixture::range( 261 check_range(
278 r###"fn test() { 262 r###"fn test() {
279 assert!(r#" 263 assert!(r#"
280$0fn foo() { 264$0fn foo() {
@@ -282,76 +266,64 @@ $0fn foo() {
282fn bar() { 266fn bar() {
283} 267}
284 "#, ""); 268 "#, "");
285}"### 269}"###,
286 .trim(), 270 expect![[r#"
287 ); 271 [email protected]
288 let syn = analysis.syntax_tree(range.file_id, Some(range.range)).unwrap(); 272 [email protected]
289 assert_eq_text!( 273 [email protected] "fn"
290 r#" 274 [email protected] " "
291[email protected] 275 [email protected]
292 [email protected] 276 [email protected] "foo"
293 [email protected] "fn" 277 [email protected]
294 [email protected] " " 278 [email protected] "("
295 [email protected] 279 [email protected] ")"
296 [email protected] "foo" 280 [email protected] " "
297 [email protected] 281 [email protected]
298 [email protected] "(" 282 [email protected] "{"
299 [email protected] ")" 283 [email protected] "\n"
300 [email protected] " " 284 [email protected] "}"
301 [email protected] 285 "#]],
302 [email protected] "{"
303 [email protected] "\n"
304 [email protected] "}"
305"#
306 .trim(),
307 syn.trim()
308 ); 286 );
309 287
310 // With a raw string 288 // With a raw string
311 let (analysis, range) = fixture::range( 289 check_range(
312 r###"fn test() { 290 r###"fn test() {
313 assert!(r$0#" 291 assert!(r$0#"
314fn foo() { 292fn foo() {
315} 293}
316fn bar() { 294fn bar() {
317}"$0#, ""); 295}"$0#, "");
318}"### 296}"###,
319 .trim(), 297 expect![[r#"
320 ); 298 [email protected]
321 let syn = analysis.syntax_tree(range.file_id, Some(range.range)).unwrap(); 299 [email protected]
322 assert_eq_text!( 300 [email protected] "fn"
323 r#" 301 [email protected] " "
324[email protected] 302 [email protected]
325 [email protected] 303 [email protected] "foo"
326 [email protected] "fn" 304 [email protected]
327 [email protected] " " 305 [email protected] "("
328 [email protected] 306 [email protected] ")"
329 [email protected] "foo" 307 [email protected] " "
330 [email protected] 308 [email protected]
331 [email protected] "(" 309 [email protected] "{"
332 [email protected] ")" 310 [email protected] "\n"
333 [email protected] " " 311 [email protected] "}"
334 [email protected] 312 [email protected] "\n"
335 [email protected] "{" 313 [email protected]
336 [email protected] "\n" 314 [email protected] "fn"
337 [email protected] "}" 315 [email protected] " "
338 [email protected] "\n" 316 [email protected]
339 [email protected] 317 [email protected] "bar"
340 [email protected] "fn" 318 [email protected]
341 [email protected] " " 319 [email protected] "("
342 [email protected] 320 [email protected] ")"
343 [email protected] "bar" 321 [email protected] " "
344 [email protected] 322 [email protected]
345 [email protected] "(" 323 [email protected] "{"
346 [email protected] ")" 324 [email protected] "\n"
347 [email protected] " " 325 [email protected] "}"
348 [email protected] 326 "#]],
349 [email protected] "{"
350 [email protected] "\n"
351 [email protected] "}"
352"#
353 .trim(),
354 syn.trim()
355 ); 327 );
356 } 328 }
357} 329}