From b84292177b5f0b7ffa8c8aad4d13495e88666737 Mon Sep 17 00:00:00 2001 From: Amber Date: Sat, 27 Jul 2024 17:54:20 -0500 Subject: [PATCH] Implement the same `safe_ident` strategy that codegen uses for parameter names that might collide with keywords Document duplicated definition of `safe_ident` Add test for `safe_ident` parameter identifier generation for `#[godot-api]` virtual call generation Remove redundant code in keyword parameter test Directly import symbols rather than using prelude --- .../special_cases/codegen_special_cases.rs | 1 + godot-codegen/src/util.rs | 1 + godot-macros/src/class/data_models/func.rs | 4 ++-- godot-macros/src/util/mod.rs | 24 +++++++++++++++++++ .../register_tests/keyword_parameters_test.rs | 21 ++++++++++++++++ itest/rust/src/register_tests/mod.rs | 1 + 6 files changed, 50 insertions(+), 2 deletions(-) create mode 100644 itest/rust/src/register_tests/keyword_parameters_test.rs diff --git a/godot-codegen/src/special_cases/codegen_special_cases.rs b/godot-codegen/src/special_cases/codegen_special_cases.rs index df02aebd1..ca111d735 100644 --- a/godot-codegen/src/special_cases/codegen_special_cases.rs +++ b/godot-codegen/src/special_cases/codegen_special_cases.rs @@ -137,6 +137,7 @@ const SELECTED_CLASSES: &[&str] = &[ "CollisionShape2D", "Control", "EditorPlugin", + "EditorExportPlugin", "Engine", "FileAccess", "GDScript", diff --git a/godot-codegen/src/util.rs b/godot-codegen/src/util.rs index 63ec0d391..dd8ef48a8 100644 --- a/godot-codegen/src/util.rs +++ b/godot-codegen/src/util.rs @@ -83,6 +83,7 @@ pub fn cstr_u8_slice(string: &str) -> Literal { Literal::byte_string(format!("{string}\0").as_bytes()) } +// This function is duplicated in godot-macros\src\util\mod.rs #[rustfmt::skip] pub fn safe_ident(s: &str) -> Ident { // See also: https://doc.rust-lang.org/reference/keywords.html diff --git a/godot-macros/src/class/data_models/func.rs b/godot-macros/src/class/data_models/func.rs index d958fd717..dea936f32 100644 --- a/godot-macros/src/class/data_models/func.rs +++ b/godot-macros/src/class/data_models/func.rs @@ -5,7 +5,7 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ -use crate::util::{bail_fn, ident}; +use crate::util::{bail_fn, ident, safe_ident}; use crate::{util, ParseResult}; use proc_macro2::{Group, Ident, TokenStream, TokenTree}; use quote::{format_ident, quote}; @@ -368,7 +368,7 @@ pub(crate) fn maybe_rename_parameter(param_ident: Ident, next_unnamed_index: &mu // This could technically collide with another parameter of the same name (without "_"), but that's very unlikely and not // something we really need to support. // Note that the case of a single "_" is handled above. - ident(remain) + safe_ident(remain) } else { param_ident } diff --git a/godot-macros/src/util/mod.rs b/godot-macros/src/util/mod.rs index f741fdacc..71e126f89 100644 --- a/godot-macros/src/util/mod.rs +++ b/godot-macros/src/util/mod.rs @@ -273,3 +273,27 @@ pub fn make_virtual_tool_check() -> TokenStream { pub fn make_virtual_tool_check() -> TokenStream { TokenStream::new() } + +// This function is duplicated in godot-codegen\src\util.rs +#[rustfmt::skip] +pub fn safe_ident(s: &str) -> Ident { + // See also: https://doc.rust-lang.org/reference/keywords.html + match s { + // Lexer + | "as" | "break" | "const" | "continue" | "crate" | "else" | "enum" | "extern" | "false" | "fn" | "for" | "if" + | "impl" | "in" | "let" | "loop" | "match" | "mod" | "move" | "mut" | "pub" | "ref" | "return" | "self" | "Self" + | "static" | "struct" | "super" | "trait" | "true" | "type" | "unsafe" | "use" | "where" | "while" + + // Lexer 2018+ + | "async" | "await" | "dyn" + + // Reserved + | "abstract" | "become" | "box" | "do" | "final" | "macro" | "override" | "priv" | "typeof" | "unsized" | "virtual" | "yield" + + // Reserved 2018+ + | "try" + => format_ident!("{}_", s), + + _ => ident(s) + } +} diff --git a/itest/rust/src/register_tests/keyword_parameters_test.rs b/itest/rust/src/register_tests/keyword_parameters_test.rs new file mode 100644 index 000000000..5ef272604 --- /dev/null +++ b/itest/rust/src/register_tests/keyword_parameters_test.rs @@ -0,0 +1,21 @@ +/* + * Copyright (c) godot-rust; Bromeon and contributors. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ + +use godot::builtin::{GString, PackedStringArray}; +use godot::classes::IEditorExportPlugin; +use godot::register::{godot_api, GodotClass}; + +#[derive(GodotClass)] +#[class(base=EditorExportPlugin, init)] +struct KeywordParameterEditorExportPlugin; + +#[godot_api] +impl IEditorExportPlugin for KeywordParameterEditorExportPlugin { + // This test requires that the second non-self parameter on `export_file` + // remain named `_type`. + fn export_file(&mut self, _path: GString, _type: GString, _features: PackedStringArray) {} +} diff --git a/itest/rust/src/register_tests/mod.rs b/itest/rust/src/register_tests/mod.rs index 10b0a3fa2..58b9dcd2e 100644 --- a/itest/rust/src/register_tests/mod.rs +++ b/itest/rust/src/register_tests/mod.rs @@ -10,6 +10,7 @@ mod conversion_test; mod derive_variant_test; mod func_test; mod gdscript_ffi_test; +mod keyword_parameters_test; mod option_ffi_test; mod var_test;