From e2b664e9fdecebd967d0c7d31e5ad5a07512b7a6 Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Fri, 7 May 2021 15:35:02 +0200 Subject: fix: use raw idents in `make::name{_ref}` with keywords --- crates/ide/src/diagnostics.rs | 20 ++++++++++++++++++++ crates/syntax/src/ast/make.rs | 14 ++++++++++++-- 2 files changed, 32 insertions(+), 2 deletions(-) (limited to 'crates') diff --git a/crates/ide/src/diagnostics.rs b/crates/ide/src/diagnostics.rs index b14f908b7..273d8cfbb 100644 --- a/crates/ide/src/diagnostics.rs +++ b/crates/ide/src/diagnostics.rs @@ -653,6 +653,26 @@ fn test_fn() { ); } + #[test] + fn test_fill_struct_fields_raw_ident() { + check_fix( + r#" +struct TestStruct { r#type: u8 } + +fn test_fn() { + TestStruct { $0 }; +} +"#, + r" +struct TestStruct { r#type: u8 } + +fn test_fn() { + TestStruct { r#type: () }; +} +", + ); + } + #[test] fn test_fill_struct_fields_no_diagnostic() { check_no_diagnostics( diff --git a/crates/syntax/src/ast/make.rs b/crates/syntax/src/ast/make.rs index 4bcea28cc..f8b508a90 100644 --- a/crates/syntax/src/ast/make.rs +++ b/crates/syntax/src/ast/make.rs @@ -15,12 +15,22 @@ use stdx::format_to; use crate::{ast, AstNode, SourceFile, SyntaxKind, SyntaxNode, SyntaxToken}; pub fn name(text: &str) -> ast::Name { - ast_from_text(&format!("mod {};", text)) + ast_from_text(&format!("mod {}{};", raw_ident_esc(text), text)) } pub fn name_ref(text: &str) -> ast::NameRef { - ast_from_text(&format!("fn f() {{ {}; }}", text)) + ast_from_text(&format!("fn f() {{ {}{}; }}", raw_ident_esc(text), text)) } + +fn raw_ident_esc(ident: &str) -> &'static str { + let is_keyword = parser::SyntaxKind::from_keyword(ident).is_some(); + if is_keyword && !matches!(ident, "self" | "crate" | "super" | "Self") { + "r#" + } else { + "" + } +} + // FIXME: replace stringly-typed constructor with a family of typed ctors, a-la // `expr_xxx`. pub fn ty(text: &str) -> ast::Type { -- cgit v1.2.3