aboutsummaryrefslogtreecommitdiff
path: root/crates/syntax/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/syntax/src')
-rw-r--r--crates/syntax/src/algo.rs26
-rw-r--r--crates/syntax/src/ast/make.rs4
-rw-r--r--crates/syntax/src/lib.rs1
-rw-r--r--crates/syntax/src/tests.rs6
-rw-r--r--crates/syntax/src/utils.rs43
5 files changed, 63 insertions, 17 deletions
diff --git a/crates/syntax/src/algo.rs b/crates/syntax/src/algo.rs
index 2ff92f9f6..b13252eec 100644
--- a/crates/syntax/src/algo.rs
+++ b/crates/syntax/src/algo.rs
@@ -10,7 +10,6 @@ use std::{
10use indexmap::IndexMap; 10use indexmap::IndexMap;
11use itertools::Itertools; 11use itertools::Itertools;
12use rustc_hash::FxHashMap; 12use rustc_hash::FxHashMap;
13use test_utils::mark;
14use text_edit::TextEditBuilder; 13use text_edit::TextEditBuilder;
15 14
16use crate::{ 15use crate::{
@@ -184,7 +183,7 @@ pub fn diff(from: &SyntaxNode, to: &SyntaxNode) -> TreeDiff {
184 let (lhs, rhs) = match lhs.as_node().zip(rhs.as_node()) { 183 let (lhs, rhs) = match lhs.as_node().zip(rhs.as_node()) {
185 Some((lhs, rhs)) => (lhs, rhs), 184 Some((lhs, rhs)) => (lhs, rhs),
186 _ => { 185 _ => {
187 mark::hit!(diff_node_token_replace); 186 cov_mark::hit!(diff_node_token_replace);
188 diff.replacements.insert(lhs, rhs); 187 diff.replacements.insert(lhs, rhs);
189 return; 188 return;
190 } 189 }
@@ -202,19 +201,19 @@ pub fn diff(from: &SyntaxNode, to: &SyntaxNode) -> TreeDiff {
202 (None, Some(element)) => { 201 (None, Some(element)) => {
203 let insert_pos = match last_lhs.clone() { 202 let insert_pos = match last_lhs.clone() {
204 Some(prev) => { 203 Some(prev) => {
205 mark::hit!(diff_insert); 204 cov_mark::hit!(diff_insert);
206 TreeDiffInsertPos::After(prev) 205 TreeDiffInsertPos::After(prev)
207 } 206 }
208 // first iteration, insert into out parent as the first child 207 // first iteration, insert into out parent as the first child
209 None => { 208 None => {
210 mark::hit!(diff_insert_as_first_child); 209 cov_mark::hit!(diff_insert_as_first_child);
211 TreeDiffInsertPos::AsFirstChild(lhs.clone().into()) 210 TreeDiffInsertPos::AsFirstChild(lhs.clone().into())
212 } 211 }
213 }; 212 };
214 diff.insertions.entry(insert_pos).or_insert_with(Vec::new).push(element); 213 diff.insertions.entry(insert_pos).or_insert_with(Vec::new).push(element);
215 } 214 }
216 (Some(element), None) => { 215 (Some(element), None) => {
217 mark::hit!(diff_delete); 216 cov_mark::hit!(diff_delete);
218 diff.deletions.push(element); 217 diff.deletions.push(element);
219 } 218 }
220 (Some(ref lhs_ele), Some(ref rhs_ele)) if syntax_element_eq(lhs_ele, rhs_ele) => {} 219 (Some(ref lhs_ele), Some(ref rhs_ele)) if syntax_element_eq(lhs_ele, rhs_ele) => {}
@@ -228,7 +227,7 @@ pub fn diff(from: &SyntaxNode, to: &SyntaxNode) -> TreeDiff {
228 let mut insert = false; 227 let mut insert = false;
229 while let Some(rhs_child) = rhs_children_clone.next() { 228 while let Some(rhs_child) = rhs_children_clone.next() {
230 if syntax_element_eq(&lhs_ele, &rhs_child) { 229 if syntax_element_eq(&lhs_ele, &rhs_child) {
231 mark::hit!(diff_insertions); 230 cov_mark::hit!(diff_insertions);
232 insert = true; 231 insert = true;
233 break; 232 break;
234 } else { 233 } else {
@@ -240,7 +239,7 @@ pub fn diff(from: &SyntaxNode, to: &SyntaxNode) -> TreeDiff {
240 let insert_pos = if let Some(prev) = last_lhs.clone().filter(|_| insert) { 239 let insert_pos = if let Some(prev) = last_lhs.clone().filter(|_| insert) {
241 TreeDiffInsertPos::After(prev) 240 TreeDiffInsertPos::After(prev)
242 } else { 241 } else {
243 mark::hit!(insert_first_child); 242 cov_mark::hit!(insert_first_child);
244 TreeDiffInsertPos::AsFirstChild(lhs.clone().into()) 243 TreeDiffInsertPos::AsFirstChild(lhs.clone().into())
245 }; 244 };
246 245
@@ -635,14 +634,13 @@ mod tests {
635 use expect_test::{expect, Expect}; 634 use expect_test::{expect, Expect};
636 use itertools::Itertools; 635 use itertools::Itertools;
637 use parser::SyntaxKind; 636 use parser::SyntaxKind;
638 use test_utils::mark;
639 use text_edit::TextEdit; 637 use text_edit::TextEdit;
640 638
641 use crate::{AstNode, SyntaxElement}; 639 use crate::{AstNode, SyntaxElement};
642 640
643 #[test] 641 #[test]
644 fn replace_node_token() { 642 fn replace_node_token() {
645 mark::check!(diff_node_token_replace); 643 cov_mark::check!(diff_node_token_replace);
646 check_diff( 644 check_diff(
647 r#"use node;"#, 645 r#"use node;"#,
648 r#"ident"#, 646 r#"ident"#,
@@ -666,7 +664,7 @@ mod tests {
666 664
667 #[test] 665 #[test]
668 fn replace_parent() { 666 fn replace_parent() {
669 mark::check!(diff_insert_as_first_child); 667 cov_mark::check!(diff_insert_as_first_child);
670 check_diff( 668 check_diff(
671 r#""#, 669 r#""#,
672 r#"use foo::bar;"#, 670 r#"use foo::bar;"#,
@@ -689,7 +687,7 @@ mod tests {
689 687
690 #[test] 688 #[test]
691 fn insert_last() { 689 fn insert_last() {
692 mark::check!(diff_insert); 690 cov_mark::check!(diff_insert);
693 check_diff( 691 check_diff(
694 r#" 692 r#"
695use foo; 693use foo;
@@ -774,7 +772,7 @@ use baz;"#,
774 772
775 #[test] 773 #[test]
776 fn first_child_insertion() { 774 fn first_child_insertion() {
777 mark::check!(insert_first_child); 775 cov_mark::check!(insert_first_child);
778 check_diff( 776 check_diff(
779 r#"fn main() { 777 r#"fn main() {
780 stdi 778 stdi
@@ -804,7 +802,7 @@ use baz;"#,
804 802
805 #[test] 803 #[test]
806 fn delete_last() { 804 fn delete_last() {
807 mark::check!(diff_delete); 805 cov_mark::check!(diff_delete);
808 check_diff( 806 check_diff(
809 r#"use foo; 807 r#"use foo;
810 use bar;"#, 808 use bar;"#,
@@ -828,7 +826,7 @@ use baz;"#,
828 826
829 #[test] 827 #[test]
830 fn delete_middle() { 828 fn delete_middle() {
831 mark::check!(diff_insertions); 829 cov_mark::check!(diff_insertions);
832 check_diff( 830 check_diff(
833 r#" 831 r#"
834use expect_test::{expect, Expect}; 832use expect_test::{expect, Expect};
diff --git a/crates/syntax/src/ast/make.rs b/crates/syntax/src/ast/make.rs
index b6c5de658..70ba8adb4 100644
--- a/crates/syntax/src/ast/make.rs
+++ b/crates/syntax/src/ast/make.rs
@@ -91,6 +91,10 @@ pub fn path_from_segments(
91 }) 91 })
92} 92}
93 93
94pub fn path_from_text(text: &str) -> ast::Path {
95 ast_from_text(&format!("fn main() {{ let test = {}; }}", text))
96}
97
94pub fn glob_use_tree() -> ast::UseTree { 98pub fn glob_use_tree() -> ast::UseTree {
95 ast_from_text("use *;") 99 ast_from_text("use *;")
96} 100}
diff --git a/crates/syntax/src/lib.rs b/crates/syntax/src/lib.rs
index 11294c5b2..09e212e8c 100644
--- a/crates/syntax/src/lib.rs
+++ b/crates/syntax/src/lib.rs
@@ -37,6 +37,7 @@ pub mod algo;
37pub mod ast; 37pub mod ast;
38#[doc(hidden)] 38#[doc(hidden)]
39pub mod fuzz; 39pub mod fuzz;
40pub mod utils;
40 41
41use std::{marker::PhantomData, sync::Arc}; 42use std::{marker::PhantomData, sync::Arc};
42 43
diff --git a/crates/syntax/src/tests.rs b/crates/syntax/src/tests.rs
index b2c06e24f..ba0ccfaed 100644
--- a/crates/syntax/src/tests.rs
+++ b/crates/syntax/src/tests.rs
@@ -7,7 +7,7 @@ use std::{
7use ast::NameOwner; 7use ast::NameOwner;
8use expect_test::expect_file; 8use expect_test::expect_file;
9use rayon::prelude::*; 9use rayon::prelude::*;
10use test_utils::{bench, bench_fixture, project_dir, skip_slow_tests}; 10use test_utils::{bench, bench_fixture, project_root, skip_slow_tests};
11 11
12use crate::{ast, fuzz, tokenize, AstNode, SourceFile, SyntaxError, TextRange, TextSize, Token}; 12use crate::{ast, fuzz, tokenize, AstNode, SourceFile, SyntaxError, TextRange, TextSize, Token};
13 13
@@ -153,7 +153,7 @@ fn reparse_fuzz_tests() {
153/// Test that Rust-analyzer can parse and validate the rust-analyzer 153/// Test that Rust-analyzer can parse and validate the rust-analyzer
154#[test] 154#[test]
155fn self_hosting_parsing() { 155fn self_hosting_parsing() {
156 let dir = project_dir().join("crates"); 156 let dir = project_root().join("crates");
157 let files = walkdir::WalkDir::new(dir) 157 let files = walkdir::WalkDir::new(dir)
158 .into_iter() 158 .into_iter()
159 .filter_entry(|entry| { 159 .filter_entry(|entry| {
@@ -193,7 +193,7 @@ fn self_hosting_parsing() {
193} 193}
194 194
195fn test_data_dir() -> PathBuf { 195fn test_data_dir() -> PathBuf {
196 project_dir().join("crates/syntax/test_data") 196 project_root().join("crates/syntax/test_data")
197} 197}
198 198
199fn assert_errors_are_present(errors: &[SyntaxError], path: &Path) { 199fn assert_errors_are_present(errors: &[SyntaxError], path: &Path) {
diff --git a/crates/syntax/src/utils.rs b/crates/syntax/src/utils.rs
new file mode 100644
index 000000000..f4c02518b
--- /dev/null
+++ b/crates/syntax/src/utils.rs
@@ -0,0 +1,43 @@
1//! A set of utils methods to reuse on other abstraction levels
2
3use itertools::Itertools;
4
5use crate::{ast, match_ast, AstNode};
6
7pub fn path_to_string_stripping_turbo_fish(path: &ast::Path) -> String {
8 path.syntax()
9 .children()
10 .filter_map(|node| {
11 match_ast! {
12 match node {
13 ast::PathSegment(it) => {
14 Some(it.name_ref()?.to_string())
15 },
16 ast::Path(it) => {
17 Some(path_to_string_stripping_turbo_fish(&it))
18 },
19 _ => None,
20 }
21 }
22 })
23 .join("::")
24}
25
26#[cfg(test)]
27mod tests {
28 use super::path_to_string_stripping_turbo_fish;
29 use crate::ast::make;
30
31 #[test]
32 fn turbofishes_are_stripped() {
33 assert_eq!("Vec", path_to_string_stripping_turbo_fish(&make::path_from_text("Vec::<i32>")),);
34 assert_eq!(
35 "Vec::new",
36 path_to_string_stripping_turbo_fish(&make::path_from_text("Vec::<i32>::new")),
37 );
38 assert_eq!(
39 "Vec::new",
40 path_to_string_stripping_turbo_fish(&make::path_from_text("Vec::new()")),
41 );
42 }
43}