about summary refs log tree commit diff
path: root/src/tools/rust-analyzer/crates/syntax
diff options
context:
space:
mode:
authorLaurențiu Nicola <lnicola@dend.ro>2022-10-18 09:12:49 +0300
committerLaurențiu Nicola <lnicola@dend.ro>2022-10-18 09:12:49 +0300
commitcb8fdff56da1b72ab942e41dc213059d83b58456 (patch)
tree621be08fef2c975ed0909cb980651134117b2359 /src/tools/rust-analyzer/crates/syntax
parent98a5ac269cffada469753ad2416717e251863f9a (diff)
parent0531aab522f25d6aae30b2cc23a09f4b9257eedc (diff)
:arrow_up: rust-analyzer
Diffstat (limited to 'src/tools/rust-analyzer/crates/syntax')
-rw-r--r--src/tools/rust-analyzer/crates/syntax/Cargo.toml8
-rw-r--r--src/tools/rust-analyzer/crates/syntax/src/ast/edit_in_place.rs56
-rw-r--r--src/tools/rust-analyzer/crates/syntax/src/ast/make.rs23
3 files changed, 78 insertions, 9 deletions
diff --git a/src/tools/rust-analyzer/crates/syntax/Cargo.toml b/src/tools/rust-analyzer/crates/syntax/Cargo.toml
index 0e2dec386ff..1ef903371cf 100644
--- a/src/tools/rust-analyzer/crates/syntax/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/syntax/Cargo.toml
@@ -12,11 +12,11 @@ doctest = false
 
 [dependencies]
 cov-mark = "2.0.0-pre.1"
-itertools = "0.10.3"
-rowan = "0.15.8"
+itertools = "0.10.5"
+rowan = "0.15.10"
 rustc_lexer = { version = "725.0.0", package = "rustc-ap-rustc_lexer" }
 rustc-hash = "1.1.0"
-once_cell = "1.12.0"
+once_cell = "1.15.0"
 indexmap = "1.9.1"
 smol_str = "0.1.23"
 
@@ -28,7 +28,7 @@ profile = { path = "../profile", version = "0.0.0" }
 [dev-dependencies]
 rayon = "1.5.3"
 expect-test = "1.4.0"
-proc-macro2 = "1.0.39"
+proc-macro2 = "1.0.47"
 quote = "1.0.20"
 ungrammar = "1.16.1"
 
diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/edit_in_place.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/edit_in_place.rs
index eadebbe8a21..229e7419b73 100644
--- a/src/tools/rust-analyzer/crates/syntax/src/ast/edit_in_place.rs
+++ b/src/tools/rust-analyzer/crates/syntax/src/ast/edit_in_place.rs
@@ -235,6 +235,24 @@ impl ast::GenericParamList {
             }
         }
     }
+
+    /// Constructs a matching [`ast::GenericArgList`]
+    pub fn to_generic_args(&self) -> ast::GenericArgList {
+        let args = self.generic_params().filter_map(|param| match param {
+            ast::GenericParam::LifetimeParam(it) => {
+                Some(ast::GenericArg::LifetimeArg(make::lifetime_arg(it.lifetime()?)))
+            }
+            ast::GenericParam::TypeParam(it) => {
+                Some(ast::GenericArg::TypeArg(make::type_arg(make::ext::ty_name(it.name()?))))
+            }
+            ast::GenericParam::ConstParam(it) => {
+                // Name-only const params get parsed as `TypeArg`s
+                Some(ast::GenericArg::TypeArg(make::type_arg(make::ext::ty_name(it.name()?))))
+            }
+        });
+
+        make::generic_arg_list(args)
+    }
 }
 
 impl ast::WhereClause {
@@ -248,6 +266,42 @@ impl ast::WhereClause {
     }
 }
 
+impl ast::TypeParam {
+    pub fn remove_default(&self) {
+        if let Some((eq, last)) = self
+            .syntax()
+            .children_with_tokens()
+            .find(|it| it.kind() == T![=])
+            .zip(self.syntax().last_child_or_token())
+        {
+            ted::remove_all(eq..=last);
+
+            // remove any trailing ws
+            if let Some(last) = self.syntax().last_token().filter(|it| it.kind() == WHITESPACE) {
+                last.detach();
+            }
+        }
+    }
+}
+
+impl ast::ConstParam {
+    pub fn remove_default(&self) {
+        if let Some((eq, last)) = self
+            .syntax()
+            .children_with_tokens()
+            .find(|it| it.kind() == T![=])
+            .zip(self.syntax().last_child_or_token())
+        {
+            ted::remove_all(eq..=last);
+
+            // remove any trailing ws
+            if let Some(last) = self.syntax().last_token().filter(|it| it.kind() == WHITESPACE) {
+                last.detach();
+            }
+        }
+    }
+}
+
 pub trait Removable: AstNode {
     fn remove(&self);
 }
@@ -264,7 +318,7 @@ impl Removable for ast::TypeBoundList {
 impl ast::PathSegment {
     pub fn get_or_create_generic_arg_list(&self) -> ast::GenericArgList {
         if self.generic_arg_list().is_none() {
-            let arg_list = make::generic_arg_list().clone_for_update();
+            let arg_list = make::generic_arg_list(empty()).clone_for_update();
             ted::append_child(self.syntax(), arg_list.syntax());
         }
         self.generic_arg_list().unwrap()
diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs
index 83f8bbac588..4057a75e7c1 100644
--- a/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs
+++ b/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs
@@ -88,6 +88,9 @@ pub mod ext {
         block_expr(None, None)
     }
 
+    pub fn ty_name(name: ast::Name) -> ast::Type {
+        ty_path(ident_path(&name.to_string()))
+    }
     pub fn ty_bool() -> ast::Type {
         ty_path(ident_path("bool"))
     }
@@ -160,6 +163,7 @@ pub fn assoc_item_list() -> ast::AssocItemList {
     ast_from_text("impl C for D {}")
 }
 
+// FIXME: `ty_params` should be `ast::GenericArgList`
 pub fn impl_(
     ty: ast::Path,
     params: Option<ast::GenericParamList>,
@@ -185,10 +189,6 @@ pub fn impl_trait(
     ast_from_text(&format!("impl{ty_params} {trait_} for {ty}{ty_params} {{}}"))
 }
 
-pub(crate) fn generic_arg_list() -> ast::GenericArgList {
-    ast_from_text("const S: T<> = ();")
-}
-
 pub fn path_segment(name_ref: ast::NameRef) -> ast::PathSegment {
     ast_from_text(&format!("type __ = {name_ref};"))
 }
@@ -718,6 +718,21 @@ pub fn generic_param_list(
     ast_from_text(&format!("fn f<{args}>() {{ }}"))
 }
 
+pub fn type_arg(ty: ast::Type) -> ast::TypeArg {
+    ast_from_text(&format!("const S: T<{ty}> = ();"))
+}
+
+pub fn lifetime_arg(lifetime: ast::Lifetime) -> ast::LifetimeArg {
+    ast_from_text(&format!("const S: T<{lifetime}> = ();"))
+}
+
+pub(crate) fn generic_arg_list(
+    args: impl IntoIterator<Item = ast::GenericArg>,
+) -> ast::GenericArgList {
+    let args = args.into_iter().join(", ");
+    ast_from_text(&format!("const S: T<{args}> = ();"))
+}
+
 pub fn visibility_pub_crate() -> ast::Visibility {
     ast_from_text("pub(crate) struct S")
 }