Skip to content

Commit 7721e13

Browse files
committed
GDScript: Add constant Array and Dictionary constructors
1 parent 0fcc198 commit 7721e13

File tree

4 files changed

+157
-11
lines changed

4 files changed

+157
-11
lines changed

modules/gdscript/gdscript_analyzer.cpp

Lines changed: 63 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5197,24 +5197,29 @@ void GDScriptAnalyzer::reduce_unary_op(GDScriptParser::UnaryOpNode *p_unary_op)
51975197
}
51985198

51995199
Variant GDScriptAnalyzer::make_expression_reduced_value(GDScriptParser::ExpressionNode *p_expression, bool &is_reduced) {
5200-
Variant value;
5201-
52025200
if (p_expression == nullptr) {
5203-
return value;
5201+
return Variant();
52045202
}
52055203

52065204
if (p_expression->is_constant) {
52075205
is_reduced = true;
5208-
value = p_expression->reduced_value;
5209-
} else if (p_expression->type == GDScriptParser::Node::ARRAY) {
5210-
value = make_array_reduced_value(static_cast<GDScriptParser::ArrayNode *>(p_expression), is_reduced);
5211-
} else if (p_expression->type == GDScriptParser::Node::DICTIONARY) {
5212-
value = make_dictionary_reduced_value(static_cast<GDScriptParser::DictionaryNode *>(p_expression), is_reduced);
5213-
} else if (p_expression->type == GDScriptParser::Node::SUBSCRIPT) {
5214-
value = make_subscript_reduced_value(static_cast<GDScriptParser::SubscriptNode *>(p_expression), is_reduced);
5206+
return p_expression->reduced_value;
52155207
}
52165208

5217-
return value;
5209+
switch (p_expression->type) {
5210+
case GDScriptParser::Node::ARRAY:
5211+
return make_array_reduced_value(static_cast<GDScriptParser::ArrayNode *>(p_expression), is_reduced);
5212+
case GDScriptParser::Node::DICTIONARY:
5213+
return make_dictionary_reduced_value(static_cast<GDScriptParser::DictionaryNode *>(p_expression), is_reduced);
5214+
case GDScriptParser::Node::SUBSCRIPT:
5215+
return make_subscript_reduced_value(static_cast<GDScriptParser::SubscriptNode *>(p_expression), is_reduced);
5216+
case GDScriptParser::Node::CALL:
5217+
return make_call_reduced_value(static_cast<GDScriptParser::CallNode *>(p_expression), is_reduced);
5218+
default:
5219+
break;
5220+
}
5221+
5222+
return Variant();
52185223
}
52195224

52205225
Variant GDScriptAnalyzer::make_array_reduced_value(GDScriptParser::ArrayNode *p_array, bool &is_reduced) {
@@ -5306,6 +5311,53 @@ Variant GDScriptAnalyzer::make_subscript_reduced_value(GDScriptParser::Subscript
53065311
}
53075312
}
53085313

5314+
Variant GDScriptAnalyzer::make_call_reduced_value(GDScriptParser::CallNode *p_call, bool &is_reduced) {
5315+
if (p_call->get_callee_type() == GDScriptParser::Node::IDENTIFIER) {
5316+
Variant::Type type = Variant::NIL;
5317+
if (p_call->function_name == SNAME("Array")) {
5318+
type = Variant::ARRAY;
5319+
} else if (p_call->function_name == SNAME("Dictionary")) {
5320+
type = Variant::DICTIONARY;
5321+
} else {
5322+
return Variant();
5323+
}
5324+
5325+
Vector<Variant> args;
5326+
args.resize(p_call->arguments.size());
5327+
const Variant **argptrs = (const Variant **)alloca(sizeof(const Variant **) * args.size());
5328+
for (int i = 0; i < p_call->arguments.size(); i++) {
5329+
bool is_arg_value_reduced = false;
5330+
Variant arg_value = make_expression_reduced_value(p_call->arguments[i], is_arg_value_reduced);
5331+
if (!is_arg_value_reduced) {
5332+
return Variant();
5333+
}
5334+
args.write[i] = arg_value;
5335+
argptrs[i] = &args[i];
5336+
}
5337+
5338+
Variant result;
5339+
Callable::CallError ce;
5340+
Variant::construct(type, result, argptrs, args.size(), ce);
5341+
if (ce.error) {
5342+
push_error(vformat(R"(Failed to construct "%s".)", Variant::get_type_name(type)), p_call);
5343+
return Variant();
5344+
}
5345+
5346+
if (type == Variant::ARRAY) {
5347+
Array array = result;
5348+
array.make_read_only();
5349+
} else if (type == Variant::DICTIONARY) {
5350+
Dictionary dictionary = result;
5351+
dictionary.make_read_only();
5352+
}
5353+
5354+
is_reduced = true;
5355+
return result;
5356+
}
5357+
5358+
return Variant();
5359+
}
5360+
53095361
Array GDScriptAnalyzer::make_array_from_element_datatype(const GDScriptParser::DataType &p_element_datatype, const GDScriptParser::Node *p_source_node) {
53105362
Array array;
53115363

modules/gdscript/gdscript_analyzer.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ class GDScriptAnalyzer {
120120
Variant make_array_reduced_value(GDScriptParser::ArrayNode *p_array, bool &is_reduced);
121121
Variant make_dictionary_reduced_value(GDScriptParser::DictionaryNode *p_dictionary, bool &is_reduced);
122122
Variant make_subscript_reduced_value(GDScriptParser::SubscriptNode *p_subscript, bool &is_reduced);
123+
Variant make_call_reduced_value(GDScriptParser::CallNode *p_call, bool &is_reduced);
123124

124125
// Helpers.
125126
Array make_array_from_element_datatype(const GDScriptParser::DataType &p_element_datatype, const GDScriptParser::Node *p_source_node = nullptr);
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
const A1 = Array()
2+
const A2 = Array(Array())
3+
const A3 = Array([])
4+
const A4 = [Array()]
5+
const A5 = [[]]
6+
const A6 = Array([1], TYPE_INT, &"", null)
7+
8+
const D1 = Dictionary()
9+
const D2 = Dictionary(Dictionary())
10+
const D3 = Dictionary({})
11+
const D4 = { Dictionary(): Dictionary() }
12+
const D5 = { {}: {} }
13+
const D6 = Dictionary({ 1: 1 }, TYPE_INT, &"", null, TYPE_INT, &"", null)
14+
15+
var a1 = Array()
16+
var a2 = Array(Array())
17+
var a3 = Array([])
18+
var a4 = [Array()]
19+
var a5 = [[]]
20+
var a6 = Array([1], TYPE_INT, &"", null)
21+
22+
var d1 = Dictionary()
23+
var d2 = Dictionary(Dictionary())
24+
var d3 = Dictionary({})
25+
var d4 = { Dictionary(): Dictionary() }
26+
var d5 = { {}: {} }
27+
var d6 = Dictionary({ 1: 1 }, TYPE_INT, &"", null, TYPE_INT, &"", null)
28+
29+
func test_value(value: Variant) -> void:
30+
@warning_ignore("unsafe_method_access")
31+
prints(value.is_read_only(), var_to_str(value).replace("\n", " "))
32+
33+
func test():
34+
print('---')
35+
test_value(A1)
36+
test_value(A2)
37+
test_value(A3)
38+
test_value(A4)
39+
test_value(A5)
40+
test_value(A6)
41+
42+
print('---')
43+
test_value(D1)
44+
test_value(D2)
45+
test_value(D3)
46+
test_value(D4)
47+
test_value(D5)
48+
test_value(D6)
49+
50+
print('---')
51+
test_value(a1)
52+
test_value(a2)
53+
test_value(a3)
54+
test_value(a4)
55+
test_value(a5)
56+
test_value(a6)
57+
58+
print('---')
59+
test_value(d1)
60+
test_value(d2)
61+
test_value(d3)
62+
test_value(d4)
63+
test_value(d5)
64+
test_value(d6)
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
GDTEST_OK
2+
---
3+
true []
4+
true []
5+
true []
6+
true [[]]
7+
true [[]]
8+
true Array[int]([1])
9+
---
10+
true {}
11+
true {}
12+
true {}
13+
true { {}: {} }
14+
true { {}: {} }
15+
true Dictionary[int, int]({ 1: 1 })
16+
---
17+
false []
18+
false []
19+
false []
20+
false [[]]
21+
false [[]]
22+
false Array[int]([1])
23+
---
24+
false {}
25+
false {}
26+
false {}
27+
false { {}: {} }
28+
false { {}: {} }
29+
false Dictionary[int, int]({ 1: 1 })

0 commit comments

Comments
 (0)