diff --git a/modules/gdscript/gdscript_analyzer.cpp b/modules/gdscript/gdscript_analyzer.cpp index 2cc37b23d2..827789cd98 100644 --- a/modules/gdscript/gdscript_analyzer.cpp +++ b/modules/gdscript/gdscript_analyzer.cpp @@ -1983,7 +1983,7 @@ void GDScriptAnalyzer::resolve_function_signature(GDScriptParser::FunctionNode * #ifdef DEBUG_ENABLED if (p_function->return_type == nullptr) { - parser->push_warning(p_function, GDScriptWarning::UNTYPED_DECLARATION, "Function", function_visible_name); + parser->push_warning(p_function->start_line, p_function->start_column, p_function->header_end_line, p_function->header_end_column, GDScriptWarning::UNTYPED_DECLARATION, "Function", function_visible_name); } #endif // DEBUG_ENABLED diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp index e4662b1167..a404b572a9 100644 --- a/modules/gdscript/gdscript_parser.cpp +++ b/modules/gdscript/gdscript_parser.cpp @@ -251,14 +251,18 @@ void GDScriptParser::push_error(const String &p_message, const Node *p_origin) { } void GDScriptParser::push_error(const String &p_message, const GDScriptTokenizer::Token &p_origin) { - panic_mode = true; + push_error(p_message, p_origin.start_line, p_origin.start_column, p_origin.end_line, p_origin.end_column); +} +void GDScriptParser::push_error(const String &p_message, int p_start_line, int p_start_column, int p_end_line, int p_end_column) { + panic_mode = true; ParserError err; err.message = p_message; - err.start_line = p_origin.start_line; - err.start_column = p_origin.start_column; - err.end_line = p_origin.end_line; - err.end_column = p_origin.end_column; + + err.start_line = p_start_line; + err.start_column = p_start_column; + err.end_line = p_end_line; + err.end_column = p_end_column; errors.push_back(err); } @@ -266,6 +270,10 @@ void GDScriptParser::push_error(const String &p_message, const GDScriptTokenizer #ifdef DEBUG_ENABLED void GDScriptParser::push_warning(const Node *p_source, GDScriptWarning::Code p_code, const Vector &p_symbols) { ERR_FAIL_NULL(p_source); + push_warning(p_source->start_line, p_source->start_column, p_source->end_line, p_source->end_column, p_code, p_symbols); +} + +void GDScriptParser::push_warning(int p_start_line, int p_start_column, int p_end_line, int p_end_column, GDScriptWarning::Code p_code, const Vector &p_symbols) { ERR_FAIL_INDEX(p_code, GDScriptWarning::WARNING_MAX); if (is_project_ignoring_warnings || is_script_ignoring_warnings) { @@ -278,7 +286,10 @@ void GDScriptParser::push_warning(const Node *p_source, GDScriptWarning::Code p_ } PendingWarning pw; - pw.source = p_source; + pw.start_line = p_start_line; + pw.start_column = p_start_column; + pw.end_line = p_end_line; + pw.end_column = p_end_column; pw.code = p_code; pw.treated_as_error = warn_level == GDScriptWarning::ERROR; pw.symbols = p_symbols; @@ -288,23 +299,23 @@ void GDScriptParser::push_warning(const Node *p_source, GDScriptWarning::Code p_ void GDScriptParser::apply_pending_warnings() { for (const PendingWarning &pw : pending_warnings) { - if (warning_ignored_lines[pw.code].has(pw.source->start_line)) { + if (warning_ignored_lines[pw.code].has(pw.start_line)) { continue; } - if (warning_ignore_start_lines[pw.code] <= pw.source->start_line) { + if (warning_ignore_start_lines[pw.code] <= pw.start_line) { continue; } GDScriptWarning warning; warning.code = pw.code; warning.symbols = pw.symbols; - warning.start_line = pw.source->start_line; - warning.start_column = pw.source->start_column; - warning.end_line = pw.source->end_line; - warning.end_column = pw.source->end_column; + warning.start_line = pw.start_line; + warning.start_column = pw.start_column; + warning.end_line = pw.end_line; + warning.end_column = pw.end_column; if (pw.treated_as_error) { - push_error(warning.get_message() + String(" (Warning treated as error.)"), pw.source); + push_error(warning.get_message() + String(" (Warning treated as error.)"), pw.start_line, pw.start_column, pw.end_line, pw.end_column); continue; } @@ -1405,6 +1416,9 @@ void GDScriptParser::parse_property_setter(VariableNode *p_variable) { consume(GDScriptTokenizer::Token::PARENTHESIS_CLOSE, R"*(Expected ")" after parameter name.)*"); consume(GDScriptTokenizer::Token::COLON, R"*(Expected ":" after ")".)*"); + function->header_end_line = previous.start_line; + function->header_end_column = previous.start_column; + FunctionNode *previous_function = current_function; current_function = function; if (p_variable->setter_parameter != nullptr) { @@ -1441,6 +1455,9 @@ void GDScriptParser::parse_property_getter(VariableNode *p_variable) { consume(GDScriptTokenizer::Token::COLON, R"(Expected ":" or "(" after "get".)"); } + function->header_end_line = previous.start_line; + function->header_end_column = previous.start_column; + IdentifierNode *identifier = alloc_node(); complete_extents(identifier); identifier->name = "@" + p_variable->identifier->name + "_getter"; @@ -1766,6 +1783,9 @@ bool GDScriptParser::parse_function_signature(FunctionNode *p_function, SuiteNod } #endif // TOOLS_ENABLED + p_function->header_end_line = previous.end_line; + p_function->header_end_column = previous.end_column; + // TODO: Improve token consumption so it synchronizes to a statement boundary. This way we can get into the function body with unrecognized tokens. if (p_type == "lambda") { return consume(GDScriptTokenizer::Token::COLON, R"(Expected ":" after lambda declaration.)"); diff --git a/modules/gdscript/gdscript_parser.h b/modules/gdscript/gdscript_parser.h index f93c77fbe6..d86a96c65f 100644 --- a/modules/gdscript/gdscript_parser.h +++ b/modules/gdscript/gdscript_parser.h @@ -869,6 +869,9 @@ public: MethodInfo info; LambdaNode *source_lambda = nullptr; Vector default_arg_values; + + int header_end_line = 0; + int header_end_column = 0; #ifdef TOOLS_ENABLED MemberDocData doc_data; int min_local_doc_line = 0; @@ -1374,7 +1377,10 @@ public: private: struct PendingWarning { - const Node *source = nullptr; + int start_line = 0; + int start_column = 0; + int end_line = 0; + int end_column = 0; GDScriptWarning::Code code = GDScriptWarning::WARNING_MAX; bool treated_as_error = false; Vector symbols; @@ -1503,6 +1509,7 @@ private: void clear(); void push_error(const String &p_message, const Node *p_origin = nullptr); + void push_error(const String &p_message, int p_start_line, int p_start_column, int p_end_line, int p_end_column); void push_error(const String &p_message, const GDScriptTokenizer::Token &p_origin); #ifdef DEBUG_ENABLED @@ -1511,6 +1518,11 @@ private: void push_warning(const Node *p_source, GDScriptWarning::Code p_code, const Symbols &...p_symbols) { push_warning(p_source, p_code, Vector{ p_symbols... }); } + void push_warning(int p_start_line, int p_start_column, int p_end_line, int p_end_column, GDScriptWarning::Code p_code, const Vector &p_symbols); + template + void push_warning(int p_start_line, int p_start_column, int p_end_line, int p_end_column, GDScriptWarning::Code p_code, const Symbols &...p_symbols) { + push_warning(p_start_line, p_start_column, p_end_line, p_end_column, p_code, Vector{ p_symbols... }); + } void apply_pending_warnings(); void evaluate_warning_directory_rules_for_script_path(); #endif // DEBUG_ENABLED