diff options
| author | Laurențiu Nicola <lnicola@dend.ro> | 2022-10-18 09:12:49 +0300 |
|---|---|---|
| committer | Laurențiu Nicola <lnicola@dend.ro> | 2022-10-18 09:12:49 +0300 |
| commit | cb8fdff56da1b72ab942e41dc213059d83b58456 (patch) | |
| tree | 621be08fef2c975ed0909cb980651134117b2359 /src/tools/rust-analyzer/crates/syntax | |
| parent | 98a5ac269cffada469753ad2416717e251863f9a (diff) | |
| parent | 0531aab522f25d6aae30b2cc23a09f4b9257eedc (diff) | |
:arrow_up: rust-analyzer
Diffstat (limited to 'src/tools/rust-analyzer/crates/syntax')
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") } |
