Skip to content

Commit 8f92a08

Browse files
authored
Merge pull request #1378 from godot-rust/bugfix/editor-plugin-no-init
Deprecate `#[class(no_init)]` for editor plugins
2 parents 61c650c + ae6885b commit 8f92a08

File tree

3 files changed

+34
-29
lines changed

3 files changed

+34
-29
lines changed

godot-core/src/deprecated.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,12 @@ pub use crate::emit_deprecated_warning;
3737
// ----------------------------------------------------------------------------------------------------------------------------------------------
3838
// Library-side deprecations -- see usage description above.
3939

40+
#[deprecated = "\n\
41+
#[class(no_init, base=EditorPlugin)] will crash when opened in the editor.\n\
42+
EditorPlugin classes are automatically instantiated by Godot and require a default constructor.\n\
43+
Use #[class(init)] instead, or provide a custom init() function in the IEditorPlugin impl."]
44+
pub const fn class_no_init_editor_plugin() {}
45+
4046
// ----------------------------------------------------------------------------------------------------------------------------------------------
4147
// Godot-side deprecations (we may mark them deprecated but keep support).
4248

godot-macros/src/class/derive_godot_class.rs

Lines changed: 27 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,7 @@ pub fn make_existence_check(ident: &Ident) -> TokenStream {
290290
// ----------------------------------------------------------------------------------------------------------------------------------------------
291291
// Implementation
292292

293-
#[derive(Copy, Clone)]
293+
#[derive(Copy, Clone, Eq, PartialEq)]
294294
enum InitStrategy {
295295
Generated,
296296
UserDefined,
@@ -531,11 +531,12 @@ fn parse_struct_attributes(class: &venial::Struct) -> ParseResult<ClassAttribute
531531
is_tool = true;
532532
}
533533

534-
// Deprecated #[class(editor_plugin)]
535-
if let Some(_attr_key) = parser.handle_alone_with_span("editor_plugin")? {
536-
deprecations.push(quote_spanned! { _attr_key.span()=>
537-
::godot::__deprecated::emit_deprecated_warning!(class_editor_plugin);
538-
});
534+
// Removed #[class(editor_plugin)]
535+
if let Some(key) = parser.handle_alone_with_span("editor_plugin")? {
536+
return bail!(
537+
key,
538+
"#[class(editor_plugin)] has been removed in favor of #[class(tool, base=EditorPlugin)]",
539+
);
539540
}
540541

541542
// #[class(rename = NewName)]
@@ -556,18 +557,24 @@ fn parse_struct_attributes(class: &venial::Struct) -> ParseResult<ClassAttribute
556557
}
557558
}
558559

559-
// Deprecated #[class(hidden)]
560-
if let Some(ident) = parser.handle_alone_with_span("hidden")? {
561-
is_internal = true;
562-
563-
deprecations.push(quote_spanned! { ident.span()=>
564-
::godot::__deprecated::emit_deprecated_warning!(class_hidden);
565-
});
560+
// Removed #[class(hidden)]
561+
if let Some(key) = parser.handle_alone_with_span("hidden")? {
562+
return bail!(
563+
key,
564+
"#[class(hidden)] has been renamed to #[class(internal)]",
565+
);
566566
}
567567

568568
parser.finish()?;
569569
}
570570

571+
// Deprecated: #[class(no_init)] with base=EditorPlugin
572+
if matches!(init_strategy, InitStrategy::Absent) && base_ty == ident("EditorPlugin") {
573+
deprecations.push(quote! {
574+
::godot::__deprecated::emit_deprecated_warning!(class_no_init_editor_plugin);
575+
});
576+
}
577+
571578
post_validate(&base_ty, is_tool)?;
572579

573580
Ok(ClassAttributes {
@@ -587,6 +594,7 @@ fn parse_fields(
587594
) -> ParseResult<Fields> {
588595
let mut all_fields = vec![];
589596
let mut base_field = Option::<Field>::None;
597+
#[allow(unused_mut)] // Less chore when adding/removing deprecations.
590598
let mut deprecations = vec![];
591599
let mut errors = vec![];
592600

@@ -633,21 +641,12 @@ fn parse_fields(
633641
});
634642
}
635643

636-
// Deprecated #[init(default = expr)]
637-
if let Some((key, default)) = parser.handle_expr_with_key("default")? {
638-
if field.default_val.is_some() {
639-
return bail!(
640-
key,
641-
"Cannot use both `val` and `default` keys in #[init]; prefer using `val`"
642-
);
643-
}
644-
field.default_val = Some(FieldDefault {
645-
default_val: default,
646-
span: parser.span(),
647-
});
648-
deprecations.push(quote_spanned! { parser.span()=>
649-
::godot::__deprecated::emit_deprecated_warning!(init_default);
650-
})
644+
// Removed #[init(default = ...)]
645+
if let Some((key, _default)) = parser.handle_expr_with_key("default")? {
646+
return bail!(
647+
key,
648+
"#[init(default = ...)] has been renamed to #[init(val = ...)]",
649+
);
651650
}
652651

653652
// #[init(node = "PATH")]

itest/rust/src/object_tests/virtual_methods_test.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -738,7 +738,7 @@ impl GetSetTest {
738738
// There isn't a good way to test editor plugins, but we can at least declare one to ensure that the macro
739739
// compiles.
740740
#[derive(GodotClass)]
741-
#[class(no_init, base = EditorPlugin, tool)]
741+
#[class(init, base = EditorPlugin, tool)]
742742
struct CustomEditorPlugin;
743743

744744
// Just override EditorPlugin::edit() to verify method is declared with Option<T>.

0 commit comments

Comments
 (0)