summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/classes/RichTextLabel.xml2
-rw-r--r--editor/plugins/sprite_frames_editor_plugin.cpp16
-rw-r--r--methods.py3
-rw-r--r--modules/gdscript/editor/gdscript_highlighter.cpp96
-rw-r--r--modules/gdscript/editor/gdscript_highlighter.h1
-rw-r--r--modules/visual_script/editor/visual_script_editor.cpp2
-rw-r--r--scene/resources/syntax_highlighter.cpp48
-rw-r--r--scene/resources/texture.cpp6
-rw-r--r--servers/rendering/shader_language.cpp445
-rw-r--r--servers/rendering/shader_language.h5
10 files changed, 232 insertions, 392 deletions
diff --git a/doc/classes/RichTextLabel.xml b/doc/classes/RichTextLabel.xml
index c8ed373271..6f5135459f 100644
--- a/doc/classes/RichTextLabel.xml
+++ b/doc/classes/RichTextLabel.xml
@@ -420,7 +420,7 @@
</member>
<member name="text" type="String" setter="set_text" getter="get_text" default="&quot;&quot;">
The label's text in BBCode format. Is not representative of manual modifications to the internal tag stack. Erases changes made by other methods when edited.
- [b]Note:[/b] If [member bbcode_enabled] is [code]true[/code], it is unadvised to use the [code]+=[/code] operator with [code]text[/code] (e.g. [code]text += "some string"[/code]) as it replaces the whole text and can cause slowdowns. Use [method append_text] for adding text instead, unless you absolutely need to close a tag that was opened in an earlier method call.
+ [b]Note:[/b] If [member bbcode_enabled] is [code]true[/code], it is unadvised to use the [code]+=[/code] operator with [code]text[/code] (e.g. [code]text += "some string"[/code]) as it replaces the whole text and can cause slowdowns. It will also erase all BBCode that was added to stack using [code]push_*[/code] methods. Use [method append_text] for adding text instead, unless you absolutely need to close a tag that was opened in an earlier method call.
</member>
<member name="text_direction" type="int" setter="set_text_direction" getter="get_text_direction" enum="Control.TextDirection" default="0">
Base text writing direction.
diff --git a/editor/plugins/sprite_frames_editor_plugin.cpp b/editor/plugins/sprite_frames_editor_plugin.cpp
index 2da4f80751..3350cec912 100644
--- a/editor/plugins/sprite_frames_editor_plugin.cpp
+++ b/editor/plugins/sprite_frames_editor_plugin.cpp
@@ -222,28 +222,14 @@ void SpriteFramesEditor::_sheet_add_frames() {
int fc = frames->get_frame_count(edited_anim);
- Point2 src_origin;
- Rect2 src_region(Point2(), texture_size);
-
- AtlasTexture *src_atlas = Object::cast_to<AtlasTexture>(*split_sheet_preview->get_texture());
- if (src_atlas && src_atlas->get_atlas().is_valid()) {
- src_origin = src_atlas->get_region().position - src_atlas->get_margin().position;
- src_region = src_atlas->get_region();
- }
-
for (Set<int>::Element *E = frames_selected.front(); E; E = E->next()) {
int idx = E->get();
Point2 frame_coords(idx % frame_count_x, idx / frame_count_x);
- Rect2 frame(frame_coords * frame_size + src_origin, frame_size);
- Rect2 region = frame.intersection(src_region);
- Rect2 margin(region == Rect2() ? Point2() : region.position - frame.position, frame.size - region.size);
-
Ref<AtlasTexture> at;
at.instantiate();
at->set_atlas(split_sheet_preview->get_texture());
- at->set_region(region);
- at->set_margin(margin);
+ at->set_region(Rect2(frame_coords * frame_size, frame_size));
undo_redo->add_do_method(frames, "add_frame", edited_anim, at, -1);
undo_redo->add_undo_method(frames, "remove_frame", edited_anim, fc);
diff --git a/methods.py b/methods.py
index 3331e159c7..86239e434c 100644
--- a/methods.py
+++ b/methods.py
@@ -780,9 +780,10 @@ def generate_vs_project(env, num_jobs):
env.vs_incs.append(str(header))
module_configs = ModuleConfigs()
- import modules.mono.build_scripts.mono_reg_utils as mono_reg
if env.get("module_mono_enabled"):
+ import modules.mono.build_scripts.mono_reg_utils as mono_reg
+
mono_root = env.get("mono_prefix") or mono_reg.find_mono_root_dir(env["bits"])
if mono_root:
module_configs.add_mode(
diff --git a/modules/gdscript/editor/gdscript_highlighter.cpp b/modules/gdscript/editor/gdscript_highlighter.cpp
index 6425123e63..5cc295bbab 100644
--- a/modules/gdscript/editor/gdscript_highlighter.cpp
+++ b/modules/gdscript/editor/gdscript_highlighter.cpp
@@ -60,7 +60,9 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l
bool in_keyword = false;
bool in_word = false;
bool in_function_name = false;
+ bool in_lambda = false;
bool in_variable_declaration = false;
+ bool in_signal_declaration = false;
bool in_function_args = false;
bool in_member_variable = false;
bool in_node_path = false;
@@ -105,12 +107,15 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l
/* color regions */
if (is_a_symbol || in_region != -1) {
int from = j;
- for (; from < line_length; from++) {
- if (str[from] == '\\') {
- from++;
- continue;
+
+ if (in_region == -1) {
+ for (; from < line_length; from++) {
+ if (str[from] == '\\') {
+ from++;
+ continue;
+ }
+ break;
}
- break;
}
if (from != line_length) {
@@ -142,6 +147,12 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l
/* check if it's the whole line */
if (end_key_length == 0 || color_regions[c].line_only || from + end_key_length > line_length) {
+ if (from + end_key_length > line_length) {
+ // If it's key length and there is a '\', dont skip to highlight esc chars.
+ if (str.find("\\", from) >= 0) {
+ break;
+ }
+ }
prev_color = color_regions[in_region].color;
highlighter_info["color"] = color_regions[c].color;
color_map[j] = highlighter_info;
@@ -161,13 +172,25 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l
/* if we are in one find the end key */
if (in_region != -1) {
+ Color region_color = color_regions[in_region].color;
+ if (in_node_path && (color_regions[in_region].start_key == "\"" || color_regions[in_region].start_key == "\'")) {
+ region_color = node_path_color;
+ }
+
+ prev_color = region_color;
+ highlighter_info["color"] = region_color;
+ color_map[j] = highlighter_info;
+
/* search the line */
int region_end_index = -1;
int end_key_length = color_regions[in_region].end_key.length();
const char32_t *end_key = color_regions[in_region].end_key.get_data();
for (; from < line_length; from++) {
if (line_length - from < end_key_length) {
- break;
+ // Don't break if '\' to highlight esc chars.
+ if (str.find("\\", from) < 0) {
+ break;
+ }
}
if (!is_symbol(str[from])) {
@@ -175,7 +198,16 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l
}
if (str[from] == '\\') {
+ Dictionary escape_char_highlighter_info;
+ escape_char_highlighter_info["color"] = symbol_color;
+ color_map[from] = escape_char_highlighter_info;
+
from++;
+
+ Dictionary region_continue_highlighter_info;
+ prev_color = region_color;
+ region_continue_highlighter_info["color"] = region_color;
+ color_map[from + 1] = region_continue_highlighter_info;
continue;
}
@@ -192,10 +224,6 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l
}
}
- prev_color = color_regions[in_region].color;
- highlighter_info["color"] = color_regions[in_region].color;
- color_map[j] = highlighter_info;
-
previous_type = REGION;
previous_text = "";
previous_column = j;
@@ -289,20 +317,36 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l
}
if (!in_function_name && in_word && !in_keyword) {
- int k = j;
- while (k < str.length() && !is_symbol(str[k]) && str[k] != '\t' && str[k] != ' ') {
- k++;
- }
+ if (previous_text == GDScriptTokenizer::get_token_name(GDScriptTokenizer::Token::SIGNAL)) {
+ in_signal_declaration = true;
+ } else {
+ int k = j;
+ while (k < str.length() && !is_symbol(str[k]) && str[k] != '\t' && str[k] != ' ') {
+ k++;
+ }
- // check for space between name and bracket
- while (k < str.length() && (str[k] == '\t' || str[k] == ' ')) {
- k++;
- }
+ // check for space between name and bracket
+ while (k < str.length() && (str[k] == '\t' || str[k] == ' ')) {
+ k++;
+ }
- if (str[k] == '(') {
- in_function_name = true;
- } else if (previous_text == GDScriptTokenizer::get_token_name(GDScriptTokenizer::Token::VAR)) {
- in_variable_declaration = true;
+ if (str[k] == '(') {
+ in_function_name = true;
+ } else if (previous_text == GDScriptTokenizer::get_token_name(GDScriptTokenizer::Token::VAR)) {
+ in_variable_declaration = true;
+ }
+
+ // Check for lambda.
+ if (in_function_name && previous_text == GDScriptTokenizer::get_token_name(GDScriptTokenizer::Token::FUNC)) {
+ k = j - 1;
+ while (k > 0 && (str[k] == '\t' || str[k] == ' ')) {
+ k--;
+ }
+
+ if (str[k] == ':') {
+ in_lambda = true;
+ }
+ }
}
}
@@ -348,7 +392,9 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l
}
in_variable_declaration = false;
+ in_signal_declaration = false;
in_function_name = false;
+ in_lambda = false;
in_member_variable = false;
}
@@ -376,10 +422,14 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l
} else if (in_member_variable) {
next_type = MEMBER;
color = member_color;
+ } else if (in_signal_declaration) {
+ next_type = SIGNAL;
+
+ color = member_color;
} else if (in_function_name) {
next_type = FUNCTION;
- if (previous_text == GDScriptTokenizer::get_token_name(GDScriptTokenizer::Token::FUNC)) {
+ if (!in_lambda && previous_text == GDScriptTokenizer::get_token_name(GDScriptTokenizer::Token::FUNC)) {
color = function_definition_color;
} else {
color = function_color;
diff --git a/modules/gdscript/editor/gdscript_highlighter.h b/modules/gdscript/editor/gdscript_highlighter.h
index ac4995bee7..1ae0d72896 100644
--- a/modules/gdscript/editor/gdscript_highlighter.h
+++ b/modules/gdscript/editor/gdscript_highlighter.h
@@ -58,6 +58,7 @@ private:
SYMBOL,
NUMBER,
FUNCTION,
+ SIGNAL,
KEYWORD,
MEMBER,
IDENTIFIER,
diff --git a/modules/visual_script/editor/visual_script_editor.cpp b/modules/visual_script/editor/visual_script_editor.cpp
index 6676d08735..ec1a8a6b42 100644
--- a/modules/visual_script/editor/visual_script_editor.cpp
+++ b/modules/visual_script/editor/visual_script_editor.cpp
@@ -2661,7 +2661,7 @@ Ref<Texture2D> VisualScriptEditor::get_theme_icon() {
}
if (Control::has_theme_icon(icon_name, "EditorIcons")) {
- return get_parent_control()->get_theme_icon(icon_name, "EditorIcons");
+ return Control::get_theme_icon(icon_name, SNAME("EditorIcons"));
}
return Control::get_theme_icon(SNAME("VisualScript"), SNAME("EditorIcons"));
diff --git a/scene/resources/syntax_highlighter.cpp b/scene/resources/syntax_highlighter.cpp
index 2efda08e08..e0aa21ac37 100644
--- a/scene/resources/syntax_highlighter.cpp
+++ b/scene/resources/syntax_highlighter.cpp
@@ -171,12 +171,15 @@ Dictionary CodeHighlighter::_get_line_syntax_highlighting_impl(int p_line) {
/* color regions */
if (is_a_symbol || in_region != -1) {
int from = j;
- for (; from < line_length; from++) {
- if (str[from] == '\\') {
- from++;
- continue;
+
+ if (in_region == -1) {
+ for (; from < line_length; from++) {
+ if (str[from] == '\\') {
+ from++;
+ continue;
+ }
+ break;
}
- break;
}
if (from != line_length) {
@@ -208,6 +211,12 @@ Dictionary CodeHighlighter::_get_line_syntax_highlighting_impl(int p_line) {
/* check if it's the whole line */
if (end_key_length == 0 || color_regions[c].line_only || from + end_key_length > line_length) {
+ if (from + end_key_length > line_length && (color_regions[in_region].start_key == "\"" || color_regions[in_region].start_key == "\'")) {
+ // If it's key length and there is a '\', dont skip to highlight esc chars.
+ if (str.find("\\", from) >= 0) {
+ break;
+ }
+ }
prev_color = color_regions[in_region].color;
highlighter_info["color"] = color_regions[c].color;
color_map[j] = highlighter_info;
@@ -227,13 +236,23 @@ Dictionary CodeHighlighter::_get_line_syntax_highlighting_impl(int p_line) {
/* if we are in one find the end key */
if (in_region != -1) {
+ bool is_string = (color_regions[in_region].start_key == "\"" || color_regions[in_region].start_key == "\'");
+
+ Color region_color = color_regions[in_region].color;
+ prev_color = region_color;
+ highlighter_info["color"] = region_color;
+ color_map[j] = highlighter_info;
+
/* search the line */
int region_end_index = -1;
int end_key_length = color_regions[in_region].end_key.length();
const char32_t *end_key = color_regions[in_region].end_key.get_data();
for (; from < line_length; from++) {
if (line_length - from < end_key_length) {
- break;
+ // Don't break if '\' to highlight esc chars.
+ if (!is_string || str.find("\\", from) < 0) {
+ break;
+ }
}
if (!is_symbol(str[from])) {
@@ -241,7 +260,20 @@ Dictionary CodeHighlighter::_get_line_syntax_highlighting_impl(int p_line) {
}
if (str[from] == '\\') {
+ if (is_string) {
+ Dictionary escape_char_highlighter_info;
+ escape_char_highlighter_info["color"] = symbol_color;
+ color_map[from] = escape_char_highlighter_info;
+ }
+
from++;
+
+ if (is_string) {
+ Dictionary region_continue_highlighter_info;
+ prev_color = region_color;
+ region_continue_highlighter_info["color"] = region_color;
+ color_map[from + 1] = region_continue_highlighter_info;
+ }
continue;
}
@@ -258,10 +290,6 @@ Dictionary CodeHighlighter::_get_line_syntax_highlighting_impl(int p_line) {
}
}
- prev_color = color_regions[in_region].color;
- highlighter_info["color"] = color_regions[in_region].color;
- color_map[j] = highlighter_info;
-
j = from + (end_key_length - 1);
if (region_end_index == -1) {
color_region_cache[p_line] = in_region;
diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp
index 28dc869c4f..331674d248 100644
--- a/scene/resources/texture.cpp
+++ b/scene/resources/texture.cpp
@@ -1156,7 +1156,7 @@ void AtlasTexture::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_m
rc.size.height = atlas->get_height();
}
- RS::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, Rect2(p_pos + margin.position, rc.size), atlas->get_rid(), rc, p_modulate, p_transpose, filter_clip);
+ atlas->draw_rect_region(p_canvas_item, Rect2(p_pos + margin.position, rc.size), rc, p_modulate, p_transpose, filter_clip);
}
void AtlasTexture::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose) const {
@@ -1177,7 +1177,7 @@ void AtlasTexture::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile
Vector2 scale = p_rect.size / (region.size + margin.size);
Rect2 dr(p_rect.position + margin.position * scale, rc.size * scale);
- RS::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, dr, atlas->get_rid(), rc, p_modulate, p_transpose, filter_clip);
+ atlas->draw_rect_region(p_canvas_item, dr, rc, p_modulate, p_transpose, filter_clip);
}
void AtlasTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, bool p_clip_uv) const {
@@ -1190,7 +1190,7 @@ void AtlasTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, cons
Rect2 src_c;
get_rect_region(p_rect, p_src_rect, dr, src_c);
- RS::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, dr, atlas->get_rid(), src_c, p_modulate, p_transpose, filter_clip);
+ atlas->draw_rect_region(p_canvas_item, dr, src_c, p_modulate, p_transpose, filter_clip);
}
bool AtlasTexture::get_rect_region(const Rect2 &p_rect, const Rect2 &p_src_rect, Rect2 &r_rect, Rect2 &r_src_rect) const {
diff --git a/servers/rendering/shader_language.cpp b/servers/rendering/shader_language.cpp
index a03ba9a02a..7641943fe9 100644
--- a/servers/rendering/shader_language.cpp
+++ b/servers/rendering/shader_language.cpp
@@ -4309,101 +4309,73 @@ bool ShaderLanguage::_propagate_function_call_sampler_builtin_reference(StringNa
ERR_FAIL_V(false); //bug? function not found
}
-ShaderLanguage::Node *ShaderLanguage::_parse_array_size(BlockNode *p_block, const FunctionInfo &p_function_info, int &r_array_size) {
- int array_size = 0;
-
- Node *n = _parse_and_reduce_expression(p_block, p_function_info);
- if (n) {
- if (n->type == Node::TYPE_VARIABLE) {
- VariableNode *vn = static_cast<VariableNode *>(n);
- if (vn) {
- ConstantNode::Value v;
- DataType data_type;
- bool is_const = false;
-
- _find_identifier(p_block, false, p_function_info, vn->name, &data_type, nullptr, &is_const, nullptr, nullptr, &v);
-
- if (is_const) {
- if (data_type == TYPE_INT) {
- int32_t value = v.sint;
- if (value > 0) {
- array_size = value;
- }
- } else if (data_type == TYPE_UINT) {
- uint32_t value = v.uint;
- if (value > 0U) {
- array_size = value;
- }
- }
- }
- }
- } else if (n->type == Node::TYPE_OPERATOR) {
- _set_error("Array size expressions are not yet implemented.");
- return nullptr;
- }
- }
-
- r_array_size = array_size;
- return n;
-}
-
-Error ShaderLanguage::_parse_global_array_size(int &r_array_size, const FunctionInfo &p_function_info) {
- if (r_array_size > 0) {
- _set_error("Array size is already defined!");
- return ERR_PARSE_ERROR;
+Error ShaderLanguage::_parse_array_size(BlockNode *p_block, const FunctionInfo &p_function_info, bool p_forbid_unknown_size, Node **r_size_expression, int *r_array_size, bool *r_unknown_size) {
+ bool error = false;
+ if (r_array_size != nullptr && *r_array_size > 0) {
+ error = true;
}
- TkPos pos = _get_tkpos();
- Token tk = _get_token();
-
- int array_size = 0;
-
- if (!tk.is_integer_constant() || ((int)tk.constant) <= 0) {
- _set_tkpos(pos);
- Node *n = _parse_array_size(nullptr, p_function_info, array_size);
- if (!n) {
- return ERR_PARSE_ERROR;
- }
- } else if (((int)tk.constant) > 0) {
- array_size = (uint32_t)tk.constant;
+ if (r_unknown_size != nullptr && *r_unknown_size) {
+ error = true;
}
-
- if (array_size <= 0) {
- _set_error("Expected single integer constant > 0");
- return ERR_PARSE_ERROR;
- }
-
- tk = _get_token();
- if (tk.type != TK_BRACKET_CLOSE) {
- _set_error("Expected ']'");
+ if (error) {
+ _set_error("Array size is already defined!");
return ERR_PARSE_ERROR;
}
- r_array_size = array_size;
- return OK;
-}
-
-Error ShaderLanguage::_parse_local_array_size(BlockNode *p_block, const FunctionInfo &p_function_info, Node *&r_size_expression, int &r_array_size, bool &r_is_unknown_size) {
TkPos pos = _get_tkpos();
Token tk = _get_token();
if (tk.type == TK_BRACKET_CLOSE) {
- r_is_unknown_size = true;
+ if (p_forbid_unknown_size) {
+ _set_error("Unknown array size is forbidden in that context!");
+ return ERR_PARSE_ERROR;
+ }
+ if (r_unknown_size != nullptr) {
+ *r_unknown_size = true;
+ }
} else {
- int size = 0;
+ int array_size = 0;
+
if (!tk.is_integer_constant() || ((int)tk.constant) <= 0) {
_set_tkpos(pos);
- int array_size = 0;
- Node *n = _parse_array_size(p_block, p_function_info, array_size);
- if (!n) {
- return ERR_PARSE_ERROR;
+ Node *n = _parse_and_reduce_expression(p_block, p_function_info);
+ if (n) {
+ if (n->type == Node::TYPE_VARIABLE) {
+ VariableNode *vn = static_cast<VariableNode *>(n);
+ if (vn) {
+ ConstantNode::Value v;
+ DataType data_type;
+ bool is_const = false;
+
+ _find_identifier(p_block, false, p_function_info, vn->name, &data_type, nullptr, &is_const, nullptr, nullptr, &v);
+
+ if (is_const) {
+ if (data_type == TYPE_INT) {
+ int32_t value = v.sint;
+ if (value > 0) {
+ array_size = value;
+ }
+ } else if (data_type == TYPE_UINT) {
+ uint32_t value = v.uint;
+ if (value > 0U) {
+ array_size = value;
+ }
+ }
+ }
+ }
+ } else if (n->type == Node::TYPE_OPERATOR) {
+ _set_error("Array size expressions are not yet implemented.");
+ return ERR_PARSE_ERROR;
+ }
+ if (r_size_expression != nullptr) {
+ *r_size_expression = n;
+ }
}
- size = array_size;
- r_size_expression = n;
} else if (((int)tk.constant) > 0) {
- size = (uint32_t)tk.constant;
+ array_size = (uint32_t)tk.constant;
}
- if (size <= 0) {
+ if (array_size <= 0) {
_set_error("Expected single integer constant > 0");
return ERR_PARSE_ERROR;
}
@@ -4414,9 +4386,10 @@ Error ShaderLanguage::_parse_local_array_size(BlockNode *p_block, const Function
return ERR_PARSE_ERROR;
}
- r_array_size = size;
+ if (r_array_size != nullptr) {
+ *r_array_size = array_size;
+ }
}
-
return OK;
}
@@ -4443,40 +4416,11 @@ ShaderLanguage::Node *ShaderLanguage::_parse_array_constructor(BlockNode *p_bloc
}
tk = _get_token();
if (tk.type == TK_BRACKET_OPEN) {
- TkPos pos = _get_tkpos();
- tk = _get_token();
- if (tk.type == TK_BRACKET_CLOSE) {
- undefined_size = true;
- tk = _get_token();
- } else {
- _set_tkpos(pos);
-
- Node *n = _parse_and_reduce_expression(p_block, p_function_info);
- if (!n || n->type != Node::TYPE_CONSTANT || n->get_datatype() != TYPE_INT) {
- _set_error("Expected single integer constant > 0");
- return nullptr;
- }
-
- ConstantNode *cnode = (ConstantNode *)n;
- if (cnode->values.size() == 1) {
- array_size = cnode->values[0].sint;
- if (array_size <= 0) {
- _set_error("Expected single integer constant > 0");
- return nullptr;
- }
- } else {
- _set_error("Expected single integer constant > 0");
- return nullptr;
- }
-
- tk = _get_token();
- if (tk.type != TK_BRACKET_CLOSE) {
- _set_error("Expected ']'");
- return nullptr;
- } else {
- tk = _get_token();
- }
+ Error error = _parse_array_size(p_block, p_function_info, false, nullptr, &array_size, &undefined_size);
+ if (error != OK) {
+ return nullptr;
}
+ tk = _get_token();
} else {
_set_error("Expected '['");
return nullptr;
@@ -4572,40 +4516,15 @@ ShaderLanguage::Node *ShaderLanguage::_parse_array_constructor(BlockNode *p_bloc
}
tk = _get_token();
if (tk.type == TK_BRACKET_OPEN) {
- TkPos pos = _get_tkpos();
- tk = _get_token();
- if (tk.type == TK_BRACKET_CLOSE) {
+ bool is_unknown_size = false;
+ Error error = _parse_array_size(p_block, p_function_info, false, nullptr, &array_size, &is_unknown_size);
+ if (error != OK) {
+ return nullptr;
+ }
+ if (is_unknown_size) {
array_size = p_array_size;
- tk = _get_token();
- } else {
- _set_tkpos(pos);
-
- Node *n = _parse_and_reduce_expression(p_block, p_function_info);
- if (!n || n->type != Node::TYPE_CONSTANT || n->get_datatype() != TYPE_INT) {
- _set_error("Expected single integer constant > 0");
- return nullptr;
- }
-
- ConstantNode *cnode = (ConstantNode *)n;
- if (cnode->values.size() == 1) {
- array_size = cnode->values[0].sint;
- if (array_size <= 0) {
- _set_error("Expected single integer constant > 0");
- return nullptr;
- }
- } else {
- _set_error("Expected single integer constant > 0");
- return nullptr;
- }
-
- tk = _get_token();
- if (tk.type != TK_BRACKET_CLOSE) {
- _set_error("Expected ']'");
- return nullptr;
- } else {
- tk = _get_token();
- }
}
+ tk = _get_token();
} else {
_set_error("Expected '['");
return nullptr;
@@ -6532,7 +6451,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
}
if (tk.type == TK_BRACKET_OPEN) {
- Error error = _parse_local_array_size(p_block, p_function_info, size_expr, array_size, unknown_size);
+ Error error = _parse_array_size(p_block, p_function_info, false, &size_expr, &array_size, &unknown_size);
if (error != OK) {
return error;
}
@@ -6587,17 +6506,12 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
bool is_array_decl = var.array_size > 0 || unknown_size;
if (tk.type == TK_BRACKET_OPEN) {
- if (is_array_decl) {
- _set_error("Array size is already defined!");
- return ERR_PARSE_ERROR;
- }
-
if (RenderingServer::get_singleton()->is_low_end() && is_const) {
_set_error("Local const arrays are supported only on high-end platform!");
return ERR_PARSE_ERROR;
}
- Error error = _parse_local_array_size(p_block, p_function_info, size_expr, var.array_size, unknown_size);
+ Error error = _parse_array_size(p_block, p_function_info, false, &size_expr, &var.array_size, &unknown_size);
if (error != OK) {
return error;
}
@@ -6702,40 +6616,15 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
tk = _get_token();
if (tk.type == TK_BRACKET_OPEN) {
- TkPos pos2 = _get_tkpos();
- tk = _get_token();
- if (tk.type == TK_BRACKET_CLOSE) {
+ bool is_unknown_size = false;
+ Error error = _parse_array_size(p_block, p_function_info, false, nullptr, &array_size2, &is_unknown_size);
+ if (error != OK) {
+ return error;
+ }
+ if (is_unknown_size) {
array_size2 = var.array_size;
- tk = _get_token();
- } else {
- _set_tkpos(pos2);
-
- Node *n = _parse_and_reduce_expression(p_block, p_function_info);
- if (!n || n->type != Node::TYPE_CONSTANT || n->get_datatype() != TYPE_INT) {
- _set_error("Expected single integer constant > 0");
- return ERR_PARSE_ERROR;
- }
-
- ConstantNode *cnode = (ConstantNode *)n;
- if (cnode->values.size() == 1) {
- array_size2 = cnode->values[0].sint;
- if (array_size2 <= 0) {
- _set_error("Expected single integer constant > 0");
- return ERR_PARSE_ERROR;
- }
- } else {
- _set_error("Expected single integer constant > 0");
- return ERR_PARSE_ERROR;
- }
-
- tk = _get_token();
- if (tk.type != TK_BRACKET_CLOSE) {
- _set_error("Expected ']'");
- return ERR_PARSE_ERROR;
- } else {
- tk = _get_token();
- }
}
+ tk = _get_token();
} else {
_set_error("Expected '['");
return ERR_PARSE_ERROR;
@@ -7764,7 +7653,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
}
if (tk.type == TK_BRACKET_OPEN) {
- Error error = _parse_global_array_size(array_size, constants);
+ Error error = _parse_array_size(nullptr, constants, true, nullptr, &array_size, nullptr);
if (error != OK) {
return error;
}
@@ -7793,7 +7682,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
tk = _get_token();
if (tk.type == TK_BRACKET_OPEN) {
- Error error = _parse_global_array_size(member->array_size, constants);
+ Error error = _parse_array_size(nullptr, constants, true, nullptr, &member->array_size, nullptr);
if (error != OK) {
return error;
}
@@ -7925,7 +7814,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
}
if (tk.type == TK_BRACKET_OPEN) {
- Error error = _parse_global_array_size(array_size, constants);
+ Error error = _parse_array_size(nullptr, constants, true, nullptr, &array_size, nullptr);
if (error != OK) {
return error;
}
@@ -7973,7 +7862,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
tk = _get_token();
if (tk.type == TK_BRACKET_OPEN) {
- Error error = _parse_global_array_size(uniform2.array_size, constants);
+ Error error = _parse_array_size(nullptr, constants, true, nullptr, &uniform2.array_size, nullptr);
if (error != OK) {
return error;
}
@@ -8308,29 +8197,11 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
}
if (tk.type == TK_BRACKET_OPEN) {
- if (array_size > 0) {
- _set_error("Array size is already defined!");
- return ERR_PARSE_ERROR;
+ Error error = _parse_array_size(nullptr, constants, true, nullptr, &varying.array_size, nullptr);
+ if (error != OK) {
+ return error;
}
tk = _get_token();
- if (tk.is_integer_constant() && tk.constant > 0) {
- varying.array_size = (int)tk.constant;
-
- tk = _get_token();
- if (tk.type == TK_BRACKET_CLOSE) {
- tk = _get_token();
- if (tk.type != TK_SEMICOLON) {
- _set_error("Expected ';'");
- return ERR_PARSE_ERROR;
- }
- } else {
- _set_error("Expected ']'");
- return ERR_PARSE_ERROR;
- }
- } else {
- _set_error("Expected integer constant > 0");
- return ERR_PARSE_ERROR;
- }
}
shader->varyings[name] = varying;
@@ -8395,36 +8266,18 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
tk = _get_token();
bool unknown_size = false;
+ bool fixed_array_size = false;
if (tk.type == TK_BRACKET_OPEN) {
if (is_constant && RenderingServer::get_singleton()->is_low_end()) {
_set_error("Global const arrays are only supported on high-end platform!");
return ERR_PARSE_ERROR;
}
- bool error = false;
- tk = _get_token();
-
- if (tk.is_integer_constant()) {
- array_size = (int)tk.constant;
- if (array_size > 0) {
- tk = _get_token();
- if (tk.type != TK_BRACKET_CLOSE) {
- _set_error("Expected ']'");
- return ERR_PARSE_ERROR;
- }
- } else {
- error = true;
- }
- } else if (tk.type == TK_BRACKET_CLOSE) {
- unknown_size = true;
- } else {
- error = true;
- }
- if (error) {
- _set_error("Expected integer constant > 0 or ']'");
- return ERR_PARSE_ERROR;
+ Error error = _parse_array_size(nullptr, constants, !is_constant, nullptr, &array_size, &unknown_size);
+ if (error != OK) {
+ return error;
}
-
+ fixed_array_size = true;
prev_pos = _get_tkpos();
}
@@ -8454,7 +8307,6 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
}
//variable
- bool first = true;
while (true) {
ShaderNode::Constant constant;
constant.name = name;
@@ -8462,34 +8314,18 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
constant.type_str = struct_name;
constant.precision = precision;
constant.initializer = nullptr;
- constant.array_size = (first ? array_size : 0);
- first = false;
+ constant.array_size = array_size;
if (tk.type == TK_BRACKET_OPEN) {
if (RenderingServer::get_singleton()->is_low_end()) {
_set_error("Global const arrays are only supported on high-end platform!");
return ERR_PARSE_ERROR;
}
- if (constant.array_size > 0 || unknown_size) {
- _set_error("Array size is already defined!");
- return ERR_PARSE_ERROR;
+ Error error = _parse_array_size(nullptr, constants, false, nullptr, &constant.array_size, &unknown_size);
+ if (error != OK) {
+ return error;
}
tk = _get_token();
- if (tk.type == TK_BRACKET_CLOSE) {
- unknown_size = true;
- tk = _get_token();
- } else if (tk.is_integer_constant() && ((int)tk.constant) > 0) {
- constant.array_size = (int)tk.constant;
- tk = _get_token();
- if (tk.type != TK_BRACKET_CLOSE) {
- _set_error("Expected ']'");
- return ERR_PARSE_ERROR;
- }
- tk = _get_token();
- } else {
- _set_error("Expected integer constant > 0 or ']'");
- return ERR_PARSE_ERROR;
- }
}
if (tk.type == TK_OP_ASSIGN) {
@@ -8540,43 +8376,18 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
}
int array_size2 = 0;
-
tk = _get_token();
+
if (tk.type == TK_BRACKET_OPEN) {
- prev_pos = _get_tkpos();
- tk = _get_token();
- if (tk.type == TK_BRACKET_CLOSE) {
+ bool is_unknown_size = false;
+ Error error = _parse_array_size(nullptr, constants, false, nullptr, &array_size2, &is_unknown_size);
+ if (error != OK) {
+ return error;
+ }
+ if (is_unknown_size) {
array_size2 = constant.array_size;
- tk = _get_token();
- } else {
- _set_tkpos(prev_pos);
-
- Node *n = _parse_and_reduce_expression(nullptr, constants);
- if (!n || n->type != Node::TYPE_CONSTANT || n->get_datatype() != TYPE_INT) {
- _set_error("Expected single integer constant > 0");
- return ERR_PARSE_ERROR;
- }
-
- ConstantNode *cnode = (ConstantNode *)n;
- if (cnode->values.size() == 1) {
- array_size2 = cnode->values[0].sint;
- if (array_size2 <= 0) {
- _set_error("Expected single integer constant > 0");
- return ERR_PARSE_ERROR;
- }
- } else {
- _set_error("Expected single integer constant > 0");
- return ERR_PARSE_ERROR;
- }
-
- tk = _get_token();
- if (tk.type != TK_BRACKET_CLOSE) {
- _set_error("Expected ']");
- return ERR_PARSE_ERROR;
- } else {
- tk = _get_token();
- }
}
+ tk = _get_token();
} else {
_set_error("Expected '[");
return ERR_PARSE_ERROR;
@@ -8674,6 +8485,8 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
}
}
+ array_size = constant.array_size;
+
ConstantNode *expr = memnew(ConstantNode);
expr->datatype = constant.type;
@@ -8746,6 +8559,11 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
tk = _get_token();
+ if (!fixed_array_size) {
+ array_size = 0;
+ }
+ unknown_size = false;
+
} else if (tk.type == TK_SEMICOLON) {
break;
} else {
@@ -8902,27 +8720,9 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
tk = _get_token();
if (tk.type == TK_BRACKET_OPEN) {
- bool error = false;
- tk = _get_token();
-
- if (tk.is_integer_constant()) {
- arg_array_size = (int)tk.constant;
-
- if (arg_array_size > 0) {
- tk = _get_token();
- if (tk.type != TK_BRACKET_CLOSE) {
- _set_error("Expected ']'");
- return ERR_PARSE_ERROR;
- }
- } else {
- error = true;
- }
- } else {
- error = true;
- }
- if (error) {
- _set_error("Expected integer constant > 0");
- return ERR_PARSE_ERROR;
+ Error error = _parse_array_size(nullptr, constants, true, nullptr, &arg_array_size, nullptr);
+ if (error != OK) {
+ return error;
}
tk = _get_token();
}
@@ -8960,32 +8760,9 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
tk = _get_token();
if (tk.type == TK_BRACKET_OPEN) {
- if (arg_array_size > 0) {
- _set_error("Array size is already defined!");
- return ERR_PARSE_ERROR;
- }
- bool error = false;
- tk = _get_token();
-
- if (tk.is_integer_constant()) {
- arg_array_size = (int)tk.constant;
-
- if (arg_array_size > 0) {
- tk = _get_token();
- if (tk.type != TK_BRACKET_CLOSE) {
- _set_error("Expected ']'");
- return ERR_PARSE_ERROR;
- }
- } else {
- error = true;
- }
- } else {
- error = true;
- }
-
- if (error) {
- _set_error("Expected integer constant > 0");
- return ERR_PARSE_ERROR;
+ Error error = _parse_array_size(nullptr, constants, true, nullptr, &arg_array_size, nullptr);
+ if (error != OK) {
+ return error;
}
tk = _get_token();
}
diff --git a/servers/rendering/shader_language.h b/servers/rendering/shader_language.h
index bc6dae7fa2..74f97319fe 100644
--- a/servers/rendering/shader_language.h
+++ b/servers/rendering/shader_language.h
@@ -1045,11 +1045,8 @@ private:
bool _validate_varying_assign(ShaderNode::Varying &p_varying, String *r_message);
bool _check_node_constness(const Node *p_node) const;
- Node *_parse_array_size(BlockNode *p_block, const FunctionInfo &p_function_info, int &r_array_size);
- Error _parse_global_array_size(int &r_array_size, const FunctionInfo &p_function_info);
- Error _parse_local_array_size(BlockNode *p_block, const FunctionInfo &p_function_info, Node *&r_size_expression, int &r_array_size, bool &r_is_unknown_size);
-
Node *_parse_expression(BlockNode *p_block, const FunctionInfo &p_function_info);
+ Error _parse_array_size(BlockNode *p_block, const FunctionInfo &p_function_info, bool p_forbid_unknown_size, Node **r_size_expression, int *r_array_size, bool *r_unknown_size);
Node *_parse_array_constructor(BlockNode *p_block, const FunctionInfo &p_function_info);
Node *_parse_array_constructor(BlockNode *p_block, const FunctionInfo &p_function_info, DataType p_type, const StringName &p_struct_name, int p_array_size);
ShaderLanguage::Node *_reduce_expression(BlockNode *p_block, ShaderLanguage::Node *p_node);