diff --git a/modules/gdscript/gdscript.cpp b/modules/gdscript/gdscript.cpp index 51a5584920fa..477b1c0e2b3c 100644 --- a/modules/gdscript/gdscript.cpp +++ b/modules/gdscript/gdscript.cpp @@ -2079,6 +2079,10 @@ String GDScriptWarning::get_message() const { CHECK_SYMBOLS(1); return "Function declaration of '" + symbols[0] + "()' conflicts with a constant of the same name."; } break; + case FUNCTION_OVERRIDES_INTERNAL_CALLBACK: { + CHECK_SYMBOLS(1); + return "Function declaration '" + symbols[0] + "()' overrides internal callback."; + } break; case INCOMPATIBLE_TERNARY: { return "Values of the ternary conditional are not mutually compatible."; } break; @@ -2158,6 +2162,7 @@ String GDScriptWarning::get_name_from_code(Code p_code) { "VARIABLE_CONFLICTS_FUNCTION", "FUNCTION_CONFLICTS_VARIABLE", "FUNCTION_CONFLICTS_CONSTANT", + "FUNCTION_OVERRIDES_INTERNAL_CALLBACK", "INCOMPATIBLE_TERNARY", "UNUSED_SIGNAL", "RETURN_VALUE_DISCARDED", diff --git a/modules/gdscript/gdscript.h b/modules/gdscript/gdscript.h index 029a5ba9b803..6b0077db7758 100644 --- a/modules/gdscript/gdscript.h +++ b/modules/gdscript/gdscript.h @@ -292,6 +292,7 @@ struct GDScriptWarning { VARIABLE_CONFLICTS_FUNCTION, // Variable has the same name of a function FUNCTION_CONFLICTS_VARIABLE, // Function has the same name of a variable FUNCTION_CONFLICTS_CONSTANT, // Function has the same name of a constant + FUNCTION_OVERRIDES_INTERNAL_CALLBACK, // Function has the same name of an internal callback prefixed with "_". INCOMPATIBLE_TERNARY, // Possible values of a ternary if are not mutually compatible UNUSED_SIGNAL, // Signal is defined but never emitted RETURN_VALUE_DISCARDED, // Function call returns something but the value isn't used diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp index daf74fa7e73a..1f8c17c527df 100644 --- a/modules/gdscript/gdscript_parser.cpp +++ b/modules/gdscript/gdscript_parser.cpp @@ -5628,6 +5628,23 @@ void GDScriptParser::_determine_inheritance(ClassNode *p_class, bool p_recursive _determine_inheritance(p_class->subclasses[i], p_recursive); } } +#ifdef DEBUG_METHODS_ENABLED + // Check whether script functions override any private callbacks in ClassDB. + List virtuals; + ClassDB::get_virtual_methods(p_class->base_type.native_type, &virtuals); + for (int i = 0; i < p_class->functions.size(); i++) { + for (const List::Element *E = virtuals.front(); E; E = E->next()) { + String func_name = p_class->functions[i]->name; + if (func_name == E->get().name) { + continue; // Overridding virtual methods is the way to go, skip. + } + if (func_name.begins_with("_") && ClassDB::has_method(p_class->base_type.native_type, func_name)) { + _add_warning(GDScriptWarning::FUNCTION_OVERRIDES_INTERNAL_CALLBACK, -1, func_name); + break; + } + } + } +#endif // DEBUG_METHODS_ENABLED } String GDScriptParser::DataType::to_string() const {