From b3704e664d23bed00b58a8e2c56d6e858f021597 Mon Sep 17 00:00:00 2001 From: PastMoments <3858420+PastMoments@users.noreply.github.com> Date: Wed, 13 Apr 2022 14:03:13 -0400 Subject: Fixes GDScript define nested dictionary and array as constants #50285 --- modules/gdscript/gdscript_analyzer.cpp | 20 ++++++++ .../analyzer/errors/invalid_array_index.out | 2 +- .../features/arrays_dictionaries_nested_const.gd | 58 ++++++++++++++++++++++ .../features/arrays_dictionaries_nested_const.out | 5 ++ 4 files changed, 84 insertions(+), 1 deletion(-) create mode 100644 modules/gdscript/tests/scripts/parser/features/arrays_dictionaries_nested_const.gd create mode 100644 modules/gdscript/tests/scripts/parser/features/arrays_dictionaries_nested_const.out (limited to 'modules/gdscript') diff --git a/modules/gdscript/gdscript_analyzer.cpp b/modules/gdscript/gdscript_analyzer.cpp index 01118a6b4f..05fb4a11c2 100644 --- a/modules/gdscript/gdscript_analyzer.cpp +++ b/modules/gdscript/gdscript_analyzer.cpp @@ -3159,6 +3159,12 @@ void GDScriptAnalyzer::reduce_subscript(GDScriptParser::SubscriptNode *p_subscri reduce_identifier(static_cast(p_subscript->base), true); } else { reduce_expression(p_subscript->base); + + if (p_subscript->base->type == GDScriptParser::Node::ARRAY) { + const_fold_array(static_cast(p_subscript->base)); + } else if (p_subscript->base->type == GDScriptParser::Node::DICTIONARY) { + const_fold_dictionary(static_cast(p_subscript->base)); + } } GDScriptParser::DataType result_type; @@ -3476,6 +3482,13 @@ void GDScriptAnalyzer::const_fold_array(GDScriptParser::ArrayNode *p_array) { for (int i = 0; i < p_array->elements.size(); i++) { GDScriptParser::ExpressionNode *element = p_array->elements[i]; + + if (element->type == GDScriptParser::Node::ARRAY) { + const_fold_array(static_cast(element)); + } else if (element->type == GDScriptParser::Node::DICTIONARY) { + const_fold_dictionary(static_cast(element)); + } + all_is_constant = all_is_constant && element->is_constant; if (!all_is_constant) { return; @@ -3496,6 +3509,13 @@ void GDScriptAnalyzer::const_fold_dictionary(GDScriptParser::DictionaryNode *p_d for (int i = 0; i < p_dictionary->elements.size(); i++) { const GDScriptParser::DictionaryNode::Pair &element = p_dictionary->elements[i]; + + if (element.value->type == GDScriptParser::Node::ARRAY) { + const_fold_array(static_cast(element.value)); + } else if (element.value->type == GDScriptParser::Node::DICTIONARY) { + const_fold_dictionary(static_cast(element.value)); + } + all_is_constant = all_is_constant && element.key->is_constant && element.value->is_constant; if (!all_is_constant) { return; diff --git a/modules/gdscript/tests/scripts/analyzer/errors/invalid_array_index.out b/modules/gdscript/tests/scripts/analyzer/errors/invalid_array_index.out index 015ad756f8..6f7f0783f0 100644 --- a/modules/gdscript/tests/scripts/analyzer/errors/invalid_array_index.out +++ b/modules/gdscript/tests/scripts/analyzer/errors/invalid_array_index.out @@ -1,2 +1,2 @@ GDTEST_ANALYZER_ERROR -Invalid index type "bool" for a base of type "Array". +Cannot get index "true" from "[0, 1]". diff --git a/modules/gdscript/tests/scripts/parser/features/arrays_dictionaries_nested_const.gd b/modules/gdscript/tests/scripts/parser/features/arrays_dictionaries_nested_const.gd new file mode 100644 index 0000000000..cc78309ae4 --- /dev/null +++ b/modules/gdscript/tests/scripts/parser/features/arrays_dictionaries_nested_const.gd @@ -0,0 +1,58 @@ +# https://github.com/godotengine/godot/issues/50285 + +@warning_ignore(unused_local_constant) +func test(): + const CONST_INNER_DICTIONARY = { "key": true } + const CONST_NESTED_DICTIONARY_OLD_WORKAROUND = { + "key1": "value1", + "key2": CONST_INNER_DICTIONARY + } + # All of these should be valid + const CONST_NESTED_DICTIONARY = { + "key1": "value1", + "key2": { "key": true } + } + + + const CONST_DICTIONARY_WITH_ARRAY = { + "key1": [1,2,3,4] + } + + const CONST_NESTED_ARRAY = [[],[2],[1,2,3]] + const CONST_ARRAY_WITH_DICT = [{"key1": 3}, {"key2": 5}] + + const THREE_DIMENSIONAL_ARRAY = [[[],[],[]],[[],[],[]],[[],[],[]]] + const MANY_NESTED_DICT = { + "key1": { + "key11": { + "key111": {}, + "key112": {}, + }, + "key12": { + "key121": {}, + "key122": {}, + }, + }, + "key2": { + "key21": { + "key211": {}, + "key212": {}, + }, + "key22": { + "key221": {}, + "key222": {}, + }, + } + } + + + const CONST_ARRAY_ACCESS = [1,2,3][0] + const CONST_DICT_ACCESS = {"key1": 5}["key1"] + + const CONST_ARRAY_NESTED_ACCESS = [[1,2,3],[4,5,6],[8,9,10]][0][1] + const CONST_DICT_NESTED_ACCESS = {"key1": {"key2": 1}}["key1"]["key2"] + + print(CONST_ARRAY_ACCESS) + print(CONST_DICT_ACCESS) + print(CONST_ARRAY_NESTED_ACCESS) + print(CONST_DICT_NESTED_ACCESS) diff --git a/modules/gdscript/tests/scripts/parser/features/arrays_dictionaries_nested_const.out b/modules/gdscript/tests/scripts/parser/features/arrays_dictionaries_nested_const.out new file mode 100644 index 0000000000..5883fc5c18 --- /dev/null +++ b/modules/gdscript/tests/scripts/parser/features/arrays_dictionaries_nested_const.out @@ -0,0 +1,5 @@ +GDTEST_OK +1 +5 +2 +1 -- cgit v1.2.3