From 5ba93619fae4eedca092bd7e4551b9034d725ff4 Mon Sep 17 00:00:00 2001 From: Yuri Roubinsky Date: Tue, 30 Nov 2021 23:28:35 +0300 Subject: [PATCH] Allow using empty statements in the shader, added formatting warning --- drivers/gles3/shader_compiler_gles3.cpp | 4 ++++ .../renderer_rd/shader_compiler_rd.cpp | 3 +++ servers/rendering/shader_language.cpp | 18 +++++++++++++++--- servers/rendering/shader_language.h | 1 + servers/rendering/shader_warnings.cpp | 4 ++++ servers/rendering/shader_warnings.h | 2 ++ tests/servers/test_shader_lang.cpp | 2 ++ 7 files changed, 31 insertions(+), 3 deletions(-) diff --git a/drivers/gles3/shader_compiler_gles3.cpp b/drivers/gles3/shader_compiler_gles3.cpp index f9443e11dbc..168080f2f10 100644 --- a/drivers/gles3/shader_compiler_gles3.cpp +++ b/drivers/gles3/shader_compiler_gles3.cpp @@ -758,6 +758,10 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener code += a + " - " + n + " * (" + a + " / " + n + "))"; } break; + case SL::OP_EMPTY: { + // Semicolon (or empty statement) - ignored. + } break; + default: { if (p_use_scope) { code += "("; diff --git a/servers/rendering/renderer_rd/shader_compiler_rd.cpp b/servers/rendering/renderer_rd/shader_compiler_rd.cpp index 77d3a2e7662..b02b3d27232 100644 --- a/servers/rendering/renderer_rd/shader_compiler_rd.cpp +++ b/servers/rendering/renderer_rd/shader_compiler_rd.cpp @@ -1318,6 +1318,9 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge code += ")"; } break; + case SL::OP_EMPTY: { + // Semicolon (or empty statement) - ignored. + } break; default: { if (p_use_scope) { diff --git a/servers/rendering/shader_language.cpp b/servers/rendering/shader_language.cpp index 8dd939ffd72..7149d386415 100644 --- a/servers/rendering/shader_language.cpp +++ b/servers/rendering/shader_language.cpp @@ -5208,9 +5208,21 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons expression.push_back(e); continue; } else { - _set_error("Expected expression, found: " + get_token_text(tk)); - return nullptr; - //nothing + if (tk.type != TK_SEMICOLON) { + _set_error("Expected expression, found: " + get_token_text(tk)); + return nullptr; + } else { +#if DEBUG_ENABLED + if (check_warnings && HAS_WARNING(ShaderWarning::FORMATTING_ERROR_FLAG)) { + _add_line_warning(ShaderWarning::FORMATTING_ERROR, "Empty statement. Remove ';' to fix this warning."); + } +#endif // DEBUG_ENABLED + _set_tkpos(prepos); + + OperatorNode *func = alloc_node(); + func->op = OP_EMPTY; + expr = func; + } } ERR_FAIL_COND_V(!expr, nullptr); diff --git a/servers/rendering/shader_language.h b/servers/rendering/shader_language.h index 193e2b72806..3de89a89a55 100644 --- a/servers/rendering/shader_language.h +++ b/servers/rendering/shader_language.h @@ -287,6 +287,7 @@ public: OP_CONSTRUCT, OP_STRUCT, OP_INDEX, + OP_EMPTY, OP_MAX }; diff --git a/servers/rendering/shader_warnings.cpp b/servers/rendering/shader_warnings.cpp index 0b8476478c9..bffae484a8c 100644 --- a/servers/rendering/shader_warnings.cpp +++ b/servers/rendering/shader_warnings.cpp @@ -61,6 +61,8 @@ String ShaderWarning::get_message() const { return vformat("The varying '%s' is declared but never used.", subject); case UNUSED_LOCAL_VARIABLE: return vformat("The local variable '%s' is declared but never used.", subject); + case FORMATTING_ERROR: + return subject; default: break; } @@ -82,6 +84,7 @@ String ShaderWarning::get_name_from_code(Code p_code) { "UNUSED_UNIFORM", "UNUSED_VARYING", "UNUSED_LOCAL_VARIABLE", + "FORMATTING_ERROR", }; static_assert((sizeof(names) / sizeof(*names)) == WARNING_MAX, "Amount of warning types don't match the amount of warning names."); @@ -110,6 +113,7 @@ static void init_code_to_flags_map() { code_to_flags_map->insert(ShaderWarning::UNUSED_UNIFORM, ShaderWarning::UNUSED_UNIFORM_FLAG); code_to_flags_map->insert(ShaderWarning::UNUSED_VARYING, ShaderWarning::UNUSED_VARYING_FLAG); code_to_flags_map->insert(ShaderWarning::UNUSED_LOCAL_VARIABLE, ShaderWarning::UNUSED_LOCAL_VARIABLE_FLAG); + code_to_flags_map->insert(ShaderWarning::FORMATTING_ERROR, ShaderWarning::FORMATTING_ERROR_FLAG); } ShaderWarning::CodeFlags ShaderWarning::get_flags_from_codemap(const Map &p_map) { diff --git a/servers/rendering/shader_warnings.h b/servers/rendering/shader_warnings.h index db872d8fb14..18915fffd88 100644 --- a/servers/rendering/shader_warnings.h +++ b/servers/rendering/shader_warnings.h @@ -47,6 +47,7 @@ public: UNUSED_UNIFORM, UNUSED_VARYING, UNUSED_LOCAL_VARIABLE, + FORMATTING_ERROR, WARNING_MAX, }; @@ -59,6 +60,7 @@ public: UNUSED_UNIFORM_FLAG = 16U, UNUSED_VARYING_FLAG = 32U, UNUSED_LOCAL_VARIABLE_FLAG = 64U, + FORMATTING_ERROR_FLAG = 128U, }; private: diff --git a/tests/servers/test_shader_lang.cpp b/tests/servers/test_shader_lang.cpp index 0591bf6adff..f4a32c67231 100644 --- a/tests/servers/test_shader_lang.cpp +++ b/tests/servers/test_shader_lang.cpp @@ -261,6 +261,8 @@ static String dump_node_code(SL::Node *p_node, int p_level) { } code += ")"; break; + case SL::OP_EMPTY: + break; default: { code = "(" + dump_node_code(onode->arguments[0], p_level) + _opstr(onode->op) + dump_node_code(onode->arguments[1], p_level) + ")"; break;