diff --git a/modules/gdscript/gdscript.cpp b/modules/gdscript/gdscript.cpp index 0676317f6ea..eada389c51e 100644 --- a/modules/gdscript/gdscript.cpp +++ b/modules/gdscript/gdscript.cpp @@ -1945,6 +1945,10 @@ String GDScriptWarning::get_message() const { CHECK_SYMBOLS(1); return "The local variable '" + symbols[0] + "' is declared but never used in the block."; } break; + case SHADOWED_VARIABLE: { + CHECK_SYMBOLS(2); + return "The local variable '" + symbols[0] + "' is shadowing an already defined variable at line " + symbols[1] + "."; + } break; case UNUSED_CLASS_VARIABLE: { CHECK_SYMBOLS(1); return "The class variable '" + symbols[0] + "' is declared but never used in the script."; @@ -2048,6 +2052,7 @@ String GDScriptWarning::get_name_from_code(Code p_code) { "UNASSIGNED_VARIABLE", "UNASSIGNED_VARIABLE_OP_ASSIGN", "UNUSED_VARIABLE", + "SHADOWED_VARIABLE", "UNUSED_CLASS_VARIABLE", "UNUSED_ARGUMENT", "UNREACHABLE_CODE", diff --git a/modules/gdscript/gdscript.h b/modules/gdscript/gdscript.h index c67e390e32e..1d75d9e2fed 100644 --- a/modules/gdscript/gdscript.h +++ b/modules/gdscript/gdscript.h @@ -273,6 +273,7 @@ struct GDScriptWarning { UNASSIGNED_VARIABLE, // Variable used but never assigned UNASSIGNED_VARIABLE_OP_ASSIGN, // Variable never assigned but used in an assignment operation (+=, *=, etc) UNUSED_VARIABLE, // Local variable is declared but never used + SHADOWED_VARIABLE, // Variable name shadowed by other variable UNUSED_CLASS_VARIABLE, // Class variable is declared but never used in the file UNUSED_ARGUMENT, // Function argument is never used UNREACHABLE_CODE, // Code after a return statement diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp index 8a9eacd8354..80af094c2ce 100644 --- a/modules/gdscript/gdscript_parser.cpp +++ b/modules/gdscript/gdscript_parser.cpp @@ -7658,6 +7658,11 @@ void GDScriptParser::_check_function_types(FunctionNode *p_function) { if (p_function->arguments_usage[i] == 0 && !p_function->arguments[i].operator String().begins_with("_")) { _add_warning(GDScriptWarning::UNUSED_ARGUMENT, p_function->line, p_function->name, p_function->arguments[i].operator String()); } + for (int j = 0; j < current_class->variables.size(); j++) { + if (current_class->variables[j].identifier == p_function->arguments[i]) { + _add_warning(GDScriptWarning::SHADOWED_VARIABLE, p_function->line, p_function->arguments[i], itos(current_class->variables[j].line)); + } + } #endif // DEBUG_ENABLED } @@ -7731,6 +7736,17 @@ void GDScriptParser::_check_function_types(FunctionNode *p_function) { p_function->return_type.has_type = false; p_function->return_type.may_yield = true; } + +#ifdef DEBUG_ENABLED + for (Map::Element *E = p_function->body->variables.front(); E; E = E->next()) { + LocalVarNode *lv = E->get(); + for (int i = 0; i < current_class->variables.size(); i++) { + if (current_class->variables[i].identifier == lv->name) { + _add_warning(GDScriptWarning::SHADOWED_VARIABLE, lv->line, lv->name, itos(current_class->variables[i].line)); + } + } + } +#endif // DEBUG_ENABLED } void GDScriptParser::_check_class_blocks_types(ClassNode *p_class) {