1 /*************************************************************************/
2 /* gdscript_parser.cpp */
3 /*************************************************************************/
4 /* This file is part of: */
5 /* GODOT ENGINE */
6 /* https://godotengine.org */
7 /*************************************************************************/
8 /* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
9 /* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
10 /* */
11 /* Permission is hereby granted, free of charge, to any person obtaining */
12 /* a copy of this software and associated documentation files (the */
13 /* "Software"), to deal in the Software without restriction, including */
14 /* without limitation the rights to use, copy, modify, merge, publish, */
15 /* distribute, sublicense, and/or sell copies of the Software, and to */
16 /* permit persons to whom the Software is furnished to do so, subject to */
17 /* the following conditions: */
18 /* */
19 /* The above copyright notice and this permission notice shall be */
20 /* included in all copies or substantial portions of the Software. */
21 /* */
22 /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23 /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24 /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
25 /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26 /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27 /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28 /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29 /*************************************************************************/
30
31 #include "gdscript_parser.h"
32
33 #include "core/core_string_names.h"
34 #include "core/engine.h"
35 #include "core/io/resource_loader.h"
36 #include "core/os/file_access.h"
37 #include "core/print_string.h"
38 #include "core/project_settings.h"
39 #include "core/reference.h"
40 #include "core/script_language.h"
41 #include "gdscript.h"
42
43 template <class T>
alloc_node()44 T *GDScriptParser::alloc_node() {
45
46 T *t = memnew(T);
47
48 t->next = list;
49 list = t;
50
51 if (!head)
52 head = t;
53
54 t->line = tokenizer->get_token_line();
55 t->column = tokenizer->get_token_column();
56 return t;
57 }
58
59 #ifdef DEBUG_ENABLED
60 static String _find_function_name(const GDScriptParser::OperatorNode *p_call);
61 #endif // DEBUG_ENABLED
62
_end_statement()63 bool GDScriptParser::_end_statement() {
64
65 if (tokenizer->get_token() == GDScriptTokenizer::TK_SEMICOLON) {
66 tokenizer->advance();
67 return true; //handle next
68 } else if (tokenizer->get_token() == GDScriptTokenizer::TK_NEWLINE || tokenizer->get_token() == GDScriptTokenizer::TK_EOF) {
69 return true; //will be handled properly
70 }
71
72 return false;
73 }
74
_set_end_statement_error(String p_name)75 void GDScriptParser::_set_end_statement_error(String p_name) {
76 String error_msg;
77 if (tokenizer->get_token() == GDScriptTokenizer::TK_IDENTIFIER) {
78 error_msg = vformat("Expected end of statement (\"%s\"), got %s (\"%s\") instead.", p_name, tokenizer->get_token_name(tokenizer->get_token()), tokenizer->get_token_identifier());
79 } else {
80 error_msg = vformat("Expected end of statement (\"%s\"), got %s instead.", p_name, tokenizer->get_token_name(tokenizer->get_token()));
81 }
82 _set_error(error_msg);
83 }
84
_enter_indent_block(BlockNode * p_block)85 bool GDScriptParser::_enter_indent_block(BlockNode *p_block) {
86
87 if (tokenizer->get_token() != GDScriptTokenizer::TK_COLON) {
88 // report location at the previous token (on the previous line)
89 int error_line = tokenizer->get_token_line(-1);
90 int error_column = tokenizer->get_token_column(-1);
91 _set_error("':' expected at end of line.", error_line, error_column);
92 return false;
93 }
94 tokenizer->advance();
95
96 if (tokenizer->get_token() == GDScriptTokenizer::TK_EOF) {
97 return false;
98 }
99
100 if (tokenizer->get_token() != GDScriptTokenizer::TK_NEWLINE) {
101 // be more python-like
102 IndentLevel current_level = indent_level.back()->get();
103 indent_level.push_back(current_level);
104 return true;
105 //_set_error("newline expected after ':'.");
106 //return false;
107 }
108
109 while (true) {
110 if (tokenizer->get_token() != GDScriptTokenizer::TK_NEWLINE) {
111
112 return false; //wtf
113 } else if (tokenizer->get_token(1) == GDScriptTokenizer::TK_EOF) {
114 return false;
115 } else if (tokenizer->get_token(1) != GDScriptTokenizer::TK_NEWLINE) {
116
117 int indent = tokenizer->get_token_line_indent();
118 int tabs = tokenizer->get_token_line_tab_indent();
119 IndentLevel current_level = indent_level.back()->get();
120 IndentLevel new_indent(indent, tabs);
121 if (new_indent.is_mixed(current_level)) {
122 _set_error("Mixed tabs and spaces in indentation.");
123 return false;
124 }
125
126 if (indent <= current_level.indent) {
127 return false;
128 }
129
130 indent_level.push_back(new_indent);
131 tokenizer->advance();
132 return true;
133
134 } else if (p_block) {
135
136 NewLineNode *nl = alloc_node<NewLineNode>();
137 nl->line = tokenizer->get_token_line();
138 p_block->statements.push_back(nl);
139 }
140
141 tokenizer->advance(); // go to next newline
142 }
143 }
144
_parse_arguments(Node * p_parent,Vector<Node * > & p_args,bool p_static,bool p_can_codecomplete,bool p_parsing_constant)145 bool GDScriptParser::_parse_arguments(Node *p_parent, Vector<Node *> &p_args, bool p_static, bool p_can_codecomplete, bool p_parsing_constant) {
146
147 if (tokenizer->get_token() == GDScriptTokenizer::TK_PARENTHESIS_CLOSE) {
148 tokenizer->advance();
149 } else {
150
151 parenthesis++;
152 int argidx = 0;
153
154 while (true) {
155
156 if (tokenizer->get_token() == GDScriptTokenizer::TK_CURSOR) {
157 _make_completable_call(argidx);
158 completion_node = p_parent;
159 } else if (tokenizer->get_token() == GDScriptTokenizer::TK_CONSTANT && tokenizer->get_token_constant().get_type() == Variant::STRING && tokenizer->get_token(1) == GDScriptTokenizer::TK_CURSOR) {
160 //completing a string argument..
161 completion_cursor = tokenizer->get_token_constant();
162
163 _make_completable_call(argidx);
164 completion_node = p_parent;
165 tokenizer->advance(1);
166 return false;
167 }
168
169 Node *arg = _parse_expression(p_parent, p_static, false, p_parsing_constant);
170 if (!arg) {
171 return false;
172 }
173
174 p_args.push_back(arg);
175
176 if (tokenizer->get_token() == GDScriptTokenizer::TK_PARENTHESIS_CLOSE) {
177 tokenizer->advance();
178 break;
179
180 } else if (tokenizer->get_token() == GDScriptTokenizer::TK_COMMA) {
181
182 if (tokenizer->get_token(1) == GDScriptTokenizer::TK_PARENTHESIS_CLOSE) {
183
184 _set_error("Expression expected");
185 return false;
186 }
187
188 tokenizer->advance();
189 argidx++;
190 } else {
191 // something is broken
192 _set_error("Expected ',' or ')'");
193 return false;
194 }
195 }
196 parenthesis--;
197 }
198
199 return true;
200 }
201
_make_completable_call(int p_arg)202 void GDScriptParser::_make_completable_call(int p_arg) {
203
204 completion_cursor = StringName();
205 completion_type = COMPLETION_CALL_ARGUMENTS;
206 completion_class = current_class;
207 completion_function = current_function;
208 completion_line = tokenizer->get_token_line();
209 completion_argument = p_arg;
210 completion_block = current_block;
211 completion_found = true;
212 tokenizer->advance();
213 }
214
_get_completable_identifier(CompletionType p_type,StringName & identifier)215 bool GDScriptParser::_get_completable_identifier(CompletionType p_type, StringName &identifier) {
216
217 identifier = StringName();
218 if (tokenizer->is_token_literal()) {
219 identifier = tokenizer->get_token_literal();
220 tokenizer->advance();
221 }
222 if (tokenizer->get_token() == GDScriptTokenizer::TK_CURSOR) {
223
224 completion_cursor = identifier;
225 completion_type = p_type;
226 completion_class = current_class;
227 completion_function = current_function;
228 completion_line = tokenizer->get_token_line();
229 completion_block = current_block;
230 completion_found = true;
231 completion_ident_is_call = false;
232 tokenizer->advance();
233
234 if (tokenizer->is_token_literal()) {
235 identifier = identifier.operator String() + tokenizer->get_token_literal().operator String();
236 tokenizer->advance();
237 }
238
239 if (tokenizer->get_token() == GDScriptTokenizer::TK_PARENTHESIS_OPEN) {
240 completion_ident_is_call = true;
241 }
242 return true;
243 }
244
245 return false;
246 }
247
_parse_expression(Node * p_parent,bool p_static,bool p_allow_assign,bool p_parsing_constant)248 GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_static, bool p_allow_assign, bool p_parsing_constant) {
249
250 //Vector<Node*> expressions;
251 //Vector<OperatorNode::Operator> operators;
252
253 Vector<Expression> expression;
254
255 Node *expr = NULL;
256
257 int op_line = tokenizer->get_token_line(); // when operators are created at the bottom, the line might have been changed (\n found)
258
259 while (true) {
260
261 /*****************/
262 /* Parse Operand */
263 /*****************/
264
265 if (parenthesis > 0) {
266 //remove empty space (only allowed if inside parenthesis
267 while (tokenizer->get_token() == GDScriptTokenizer::TK_NEWLINE) {
268 tokenizer->advance();
269 }
270 }
271
272 // Check that the next token is not TK_CURSOR and if it is, the offset should be incremented.
273 int next_valid_offset = 1;
274 if (tokenizer->get_token(next_valid_offset) == GDScriptTokenizer::TK_CURSOR) {
275 next_valid_offset++;
276 // There is a chunk of the identifier that also needs to be ignored (not always there!)
277 if (tokenizer->get_token(next_valid_offset) == GDScriptTokenizer::TK_IDENTIFIER) {
278 next_valid_offset++;
279 }
280 }
281
282 if (tokenizer->get_token() == GDScriptTokenizer::TK_PARENTHESIS_OPEN) {
283 //subexpression ()
284 tokenizer->advance();
285 parenthesis++;
286 Node *subexpr = _parse_expression(p_parent, p_static, p_allow_assign, p_parsing_constant);
287 parenthesis--;
288 if (!subexpr)
289 return NULL;
290
291 if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_CLOSE) {
292
293 _set_error("Expected ')' in expression");
294 return NULL;
295 }
296
297 tokenizer->advance();
298 expr = subexpr;
299 } else if (tokenizer->get_token() == GDScriptTokenizer::TK_DOLLAR) {
300 tokenizer->advance();
301
302 String path;
303
304 bool need_identifier = true;
305 bool done = false;
306 int line = tokenizer->get_token_line();
307
308 while (!done) {
309
310 switch (tokenizer->get_token()) {
311 case GDScriptTokenizer::TK_CURSOR: {
312 completion_type = COMPLETION_GET_NODE;
313 completion_class = current_class;
314 completion_function = current_function;
315 completion_line = tokenizer->get_token_line();
316 completion_cursor = path;
317 completion_argument = 0;
318 completion_block = current_block;
319 completion_found = true;
320 tokenizer->advance();
321 } break;
322 case GDScriptTokenizer::TK_CONSTANT: {
323
324 if (!need_identifier) {
325 done = true;
326 break;
327 }
328
329 if (tokenizer->get_token_constant().get_type() != Variant::STRING) {
330 _set_error("Expected string constant or identifier after '$' or '/'.");
331 return NULL;
332 }
333
334 path += String(tokenizer->get_token_constant());
335 tokenizer->advance();
336 need_identifier = false;
337
338 } break;
339 case GDScriptTokenizer::TK_OP_DIV: {
340
341 if (need_identifier) {
342 done = true;
343 break;
344 }
345
346 path += "/";
347 tokenizer->advance();
348 need_identifier = true;
349
350 } break;
351 default: {
352 // Instead of checking for TK_IDENTIFIER, we check with is_token_literal, as this allows us to use match/sync/etc. as a name
353 if (need_identifier && tokenizer->is_token_literal()) {
354 path += String(tokenizer->get_token_literal());
355 tokenizer->advance();
356 need_identifier = false;
357 } else {
358 done = true;
359 }
360
361 break;
362 }
363 }
364 }
365
366 if (path == "") {
367 _set_error("Path expected after $.");
368 return NULL;
369 }
370
371 OperatorNode *op = alloc_node<OperatorNode>();
372 op->op = OperatorNode::OP_CALL;
373 op->line = line;
374 op->arguments.push_back(alloc_node<SelfNode>());
375 op->arguments[0]->line = line;
376
377 IdentifierNode *funcname = alloc_node<IdentifierNode>();
378 funcname->name = "get_node";
379 funcname->line = line;
380 op->arguments.push_back(funcname);
381
382 ConstantNode *nodepath = alloc_node<ConstantNode>();
383 nodepath->value = NodePath(StringName(path));
384 nodepath->datatype = _type_from_variant(nodepath->value);
385 nodepath->line = line;
386 op->arguments.push_back(nodepath);
387
388 expr = op;
389
390 } else if (tokenizer->get_token() == GDScriptTokenizer::TK_CURSOR) {
391 tokenizer->advance();
392 continue; //no point in cursor in the middle of expression
393
394 } else if (tokenizer->get_token() == GDScriptTokenizer::TK_CONSTANT) {
395
396 //constant defined by tokenizer
397 ConstantNode *constant = alloc_node<ConstantNode>();
398 constant->value = tokenizer->get_token_constant();
399 constant->datatype = _type_from_variant(constant->value);
400 tokenizer->advance();
401 expr = constant;
402 } else if (tokenizer->get_token() == GDScriptTokenizer::TK_CONST_PI) {
403
404 //constant defined by tokenizer
405 ConstantNode *constant = alloc_node<ConstantNode>();
406 constant->value = Math_PI;
407 constant->datatype = _type_from_variant(constant->value);
408 tokenizer->advance();
409 expr = constant;
410 } else if (tokenizer->get_token() == GDScriptTokenizer::TK_CONST_TAU) {
411
412 //constant defined by tokenizer
413 ConstantNode *constant = alloc_node<ConstantNode>();
414 constant->value = Math_TAU;
415 constant->datatype = _type_from_variant(constant->value);
416 tokenizer->advance();
417 expr = constant;
418 } else if (tokenizer->get_token() == GDScriptTokenizer::TK_CONST_INF) {
419
420 //constant defined by tokenizer
421 ConstantNode *constant = alloc_node<ConstantNode>();
422 constant->value = Math_INF;
423 constant->datatype = _type_from_variant(constant->value);
424 tokenizer->advance();
425 expr = constant;
426 } else if (tokenizer->get_token() == GDScriptTokenizer::TK_CONST_NAN) {
427
428 //constant defined by tokenizer
429 ConstantNode *constant = alloc_node<ConstantNode>();
430 constant->value = Math_NAN;
431 constant->datatype = _type_from_variant(constant->value);
432 tokenizer->advance();
433 expr = constant;
434 } else if (tokenizer->get_token() == GDScriptTokenizer::TK_PR_PRELOAD) {
435
436 //constant defined by tokenizer
437 tokenizer->advance();
438 if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_OPEN) {
439 _set_error("Expected '(' after 'preload'");
440 return NULL;
441 }
442 tokenizer->advance();
443
444 if (tokenizer->get_token() == GDScriptTokenizer::TK_CURSOR) {
445 completion_cursor = StringName();
446 completion_node = p_parent;
447 completion_type = COMPLETION_RESOURCE_PATH;
448 completion_class = current_class;
449 completion_function = current_function;
450 completion_line = tokenizer->get_token_line();
451 completion_block = current_block;
452 completion_argument = 0;
453 completion_found = true;
454 tokenizer->advance();
455 }
456
457 String path;
458 bool found_constant = false;
459 bool valid = false;
460 ConstantNode *cn;
461
462 Node *subexpr = _parse_and_reduce_expression(p_parent, p_static);
463 if (subexpr) {
464 if (subexpr->type == Node::TYPE_CONSTANT) {
465 cn = static_cast<ConstantNode *>(subexpr);
466 found_constant = true;
467 }
468 if (subexpr->type == Node::TYPE_IDENTIFIER) {
469 IdentifierNode *in = static_cast<IdentifierNode *>(subexpr);
470
471 // Try to find the constant expression by the identifier
472 if (current_class->constant_expressions.has(in->name)) {
473 Node *cn_exp = current_class->constant_expressions[in->name].expression;
474 if (cn_exp->type == Node::TYPE_CONSTANT) {
475 cn = static_cast<ConstantNode *>(cn_exp);
476 found_constant = true;
477 }
478 }
479 }
480
481 if (found_constant && cn->value.get_type() == Variant::STRING) {
482 valid = true;
483 path = (String)cn->value;
484 }
485 }
486
487 if (!valid) {
488 _set_error("expected string constant as 'preload' argument.");
489 return NULL;
490 }
491
492 if (!path.is_abs_path() && base_path != "")
493 path = base_path.plus_file(path);
494 path = path.replace("///", "//").simplify_path();
495 if (path == self_path) {
496
497 _set_error("Can't preload itself (use 'get_script()').");
498 return NULL;
499 }
500
501 Ref<Resource> res;
502 dependencies.push_back(path);
503 if (!dependencies_only) {
504 if (!validating) {
505
506 //this can be too slow for just validating code
507 if (for_completion && ScriptCodeCompletionCache::get_singleton() && FileAccess::exists(path)) {
508 res = ScriptCodeCompletionCache::get_singleton()->get_cached_resource(path);
509 } else if (!for_completion || FileAccess::exists(path)) {
510 res = ResourceLoader::load(path);
511 }
512 } else {
513
514 if (!FileAccess::exists(path)) {
515 _set_error("Can't preload resource at path: " + path);
516 return NULL;
517 } else if (ScriptCodeCompletionCache::get_singleton()) {
518 res = ScriptCodeCompletionCache::get_singleton()->get_cached_resource(path);
519 }
520 }
521 if (!res.is_valid()) {
522 _set_error("Can't preload resource at path: " + path);
523 return NULL;
524 }
525 }
526
527 if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_CLOSE) {
528 _set_error("Expected ')' after 'preload' path");
529 return NULL;
530 }
531
532 Ref<GDScript> gds = res;
533 if (gds.is_valid() && !gds->is_valid()) {
534 _set_error("Couldn't fully preload the script, possible cyclic reference or compilation error. Use \"load()\" instead if a cyclic reference is intended.");
535 return NULL;
536 }
537
538 tokenizer->advance();
539
540 ConstantNode *constant = alloc_node<ConstantNode>();
541 constant->value = res;
542 constant->datatype = _type_from_variant(constant->value);
543
544 expr = constant;
545 } else if (tokenizer->get_token() == GDScriptTokenizer::TK_PR_YIELD) {
546
547 if (!current_function) {
548 _set_error("\"yield()\" can only be used inside function blocks.");
549 return NULL;
550 }
551
552 current_function->has_yield = true;
553
554 tokenizer->advance();
555 if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_OPEN) {
556 _set_error("Expected \"(\" after \"yield\".");
557 return NULL;
558 }
559
560 tokenizer->advance();
561
562 OperatorNode *yield = alloc_node<OperatorNode>();
563 yield->op = OperatorNode::OP_YIELD;
564
565 while (tokenizer->get_token() == GDScriptTokenizer::TK_NEWLINE) {
566 tokenizer->advance();
567 }
568
569 if (tokenizer->get_token() == GDScriptTokenizer::TK_PARENTHESIS_CLOSE) {
570 expr = yield;
571 tokenizer->advance();
572 } else {
573
574 parenthesis++;
575
576 Node *object = _parse_and_reduce_expression(p_parent, p_static);
577 if (!object)
578 return NULL;
579 yield->arguments.push_back(object);
580
581 if (tokenizer->get_token() != GDScriptTokenizer::TK_COMMA) {
582 _set_error("Expected \",\" after the first argument of \"yield\".");
583 return NULL;
584 }
585
586 tokenizer->advance();
587
588 if (tokenizer->get_token() == GDScriptTokenizer::TK_CURSOR) {
589
590 completion_cursor = StringName();
591 completion_node = object;
592 completion_type = COMPLETION_YIELD;
593 completion_class = current_class;
594 completion_function = current_function;
595 completion_line = tokenizer->get_token_line();
596 completion_argument = 0;
597 completion_block = current_block;
598 completion_found = true;
599 tokenizer->advance();
600 }
601
602 Node *signal = _parse_and_reduce_expression(p_parent, p_static);
603 if (!signal)
604 return NULL;
605 yield->arguments.push_back(signal);
606
607 if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_CLOSE) {
608 _set_error("Expected \")\" after the second argument of \"yield\".");
609 return NULL;
610 }
611
612 parenthesis--;
613
614 tokenizer->advance();
615
616 expr = yield;
617 }
618
619 } else if (tokenizer->get_token() == GDScriptTokenizer::TK_SELF) {
620
621 if (p_static) {
622 _set_error("\"self\" isn't allowed in a static function or constant expression.");
623 return NULL;
624 }
625 //constant defined by tokenizer
626 SelfNode *self = alloc_node<SelfNode>();
627 tokenizer->advance();
628 expr = self;
629 } else if (tokenizer->get_token() == GDScriptTokenizer::TK_BUILT_IN_TYPE && tokenizer->get_token(1) == GDScriptTokenizer::TK_PERIOD) {
630
631 Variant::Type bi_type = tokenizer->get_token_type();
632 tokenizer->advance(2);
633
634 StringName identifier;
635
636 if (_get_completable_identifier(COMPLETION_BUILT_IN_TYPE_CONSTANT, identifier)) {
637
638 completion_built_in_constant = bi_type;
639 }
640
641 if (identifier == StringName()) {
642
643 _set_error("Built-in type constant or static function expected after \".\".");
644 return NULL;
645 }
646 if (!Variant::has_constant(bi_type, identifier)) {
647
648 if (tokenizer->get_token() == GDScriptTokenizer::TK_PARENTHESIS_OPEN &&
649 Variant::is_method_const(bi_type, identifier) &&
650 Variant::get_method_return_type(bi_type, identifier) == bi_type) {
651
652 tokenizer->advance();
653
654 OperatorNode *construct = alloc_node<OperatorNode>();
655 construct->op = OperatorNode::OP_CALL;
656
657 TypeNode *tn = alloc_node<TypeNode>();
658 tn->vtype = bi_type;
659 construct->arguments.push_back(tn);
660
661 OperatorNode *op = alloc_node<OperatorNode>();
662 op->op = OperatorNode::OP_CALL;
663 op->arguments.push_back(construct);
664
665 IdentifierNode *id = alloc_node<IdentifierNode>();
666 id->name = identifier;
667 op->arguments.push_back(id);
668
669 if (!_parse_arguments(op, op->arguments, p_static, true, p_parsing_constant))
670 return NULL;
671
672 expr = op;
673 } else {
674 // Object is a special case
675 bool valid = false;
676 if (bi_type == Variant::OBJECT) {
677 int object_constant = ClassDB::get_integer_constant("Object", identifier, &valid);
678 if (valid) {
679 ConstantNode *cn = alloc_node<ConstantNode>();
680 cn->value = object_constant;
681 cn->datatype = _type_from_variant(cn->value);
682 expr = cn;
683 }
684 }
685 if (!valid) {
686 _set_error("Static constant '" + identifier.operator String() + "' not present in built-in type " + Variant::get_type_name(bi_type) + ".");
687 return NULL;
688 }
689 }
690 } else {
691
692 ConstantNode *cn = alloc_node<ConstantNode>();
693 cn->value = Variant::get_constant_value(bi_type, identifier);
694 cn->datatype = _type_from_variant(cn->value);
695 expr = cn;
696 }
697
698 } else if (tokenizer->get_token(next_valid_offset) == GDScriptTokenizer::TK_PARENTHESIS_OPEN && tokenizer->is_token_literal()) {
699 // We check with is_token_literal, as this allows us to use match/sync/etc. as a name
700 //function or constructor
701
702 OperatorNode *op = alloc_node<OperatorNode>();
703 op->op = OperatorNode::OP_CALL;
704
705 //Do a quick Array and Dictionary Check. Replace if either require no arguments.
706 bool replaced = false;
707
708 if (tokenizer->get_token() == GDScriptTokenizer::TK_BUILT_IN_TYPE) {
709 Variant::Type ct = tokenizer->get_token_type();
710 if (!p_parsing_constant) {
711 if (ct == Variant::ARRAY) {
712 if (tokenizer->get_token(2) == GDScriptTokenizer::TK_PARENTHESIS_CLOSE) {
713 ArrayNode *arr = alloc_node<ArrayNode>();
714 expr = arr;
715 replaced = true;
716 tokenizer->advance(3);
717 }
718 }
719 if (ct == Variant::DICTIONARY) {
720 if (tokenizer->get_token(2) == GDScriptTokenizer::TK_PARENTHESIS_CLOSE) {
721 DictionaryNode *dict = alloc_node<DictionaryNode>();
722 expr = dict;
723 replaced = true;
724 tokenizer->advance(3);
725 }
726 }
727 }
728
729 if (!replaced) {
730 TypeNode *tn = alloc_node<TypeNode>();
731 tn->vtype = tokenizer->get_token_type();
732 op->arguments.push_back(tn);
733 tokenizer->advance(2);
734 }
735 } else if (tokenizer->get_token() == GDScriptTokenizer::TK_BUILT_IN_FUNC) {
736
737 BuiltInFunctionNode *bn = alloc_node<BuiltInFunctionNode>();
738 bn->function = tokenizer->get_token_built_in_func();
739 op->arguments.push_back(bn);
740 tokenizer->advance(2);
741 } else {
742
743 SelfNode *self = alloc_node<SelfNode>();
744 op->arguments.push_back(self);
745
746 StringName identifier;
747 if (_get_completable_identifier(COMPLETION_FUNCTION, identifier)) {
748 }
749
750 IdentifierNode *id = alloc_node<IdentifierNode>();
751 id->name = identifier;
752 op->arguments.push_back(id);
753 tokenizer->advance(1);
754 }
755
756 if (tokenizer->get_token() == GDScriptTokenizer::TK_CURSOR) {
757 _make_completable_call(0);
758 completion_node = op;
759 }
760 if (!replaced) {
761 if (!_parse_arguments(op, op->arguments, p_static, true, p_parsing_constant))
762 return NULL;
763 expr = op;
764 }
765 } else if (tokenizer->is_token_literal(0, true)) {
766 // We check with is_token_literal, as this allows us to use match/sync/etc. as a name
767 //identifier (reference)
768
769 const ClassNode *cln = current_class;
770 bool bfn = false;
771 StringName identifier;
772 int id_line = tokenizer->get_token_line();
773 if (_get_completable_identifier(COMPLETION_IDENTIFIER, identifier)) {
774 }
775
776 BlockNode *b = current_block;
777 while (!bfn && b) {
778 if (b->variables.has(identifier)) {
779 IdentifierNode *id = alloc_node<IdentifierNode>();
780 id->name = identifier;
781 id->declared_block = b;
782 id->line = id_line;
783 expr = id;
784 bfn = true;
785
786 #ifdef DEBUG_ENABLED
787 LocalVarNode *lv = b->variables[identifier];
788 switch (tokenizer->get_token()) {
789 case GDScriptTokenizer::TK_OP_ASSIGN_ADD:
790 case GDScriptTokenizer::TK_OP_ASSIGN_BIT_AND:
791 case GDScriptTokenizer::TK_OP_ASSIGN_BIT_OR:
792 case GDScriptTokenizer::TK_OP_ASSIGN_BIT_XOR:
793 case GDScriptTokenizer::TK_OP_ASSIGN_DIV:
794 case GDScriptTokenizer::TK_OP_ASSIGN_MOD:
795 case GDScriptTokenizer::TK_OP_ASSIGN_MUL:
796 case GDScriptTokenizer::TK_OP_ASSIGN_SHIFT_LEFT:
797 case GDScriptTokenizer::TK_OP_ASSIGN_SHIFT_RIGHT:
798 case GDScriptTokenizer::TK_OP_ASSIGN_SUB: {
799 if (lv->assignments == 0) {
800 if (!lv->datatype.has_type) {
801 _set_error("Using assignment with operation on a variable that was never assigned.");
802 return NULL;
803 }
804 _add_warning(GDScriptWarning::UNASSIGNED_VARIABLE_OP_ASSIGN, -1, identifier.operator String());
805 }
806 FALLTHROUGH;
807 }
808 case GDScriptTokenizer::TK_OP_ASSIGN: {
809 lv->assignments += 1;
810 lv->usages--; // Assignment is not really usage
811 } break;
812 default: {
813 lv->usages++;
814 }
815 }
816 #endif // DEBUG_ENABLED
817 break;
818 }
819 b = b->parent_block;
820 }
821
822 if (!bfn && p_parsing_constant) {
823 if (cln->constant_expressions.has(identifier)) {
824 expr = cln->constant_expressions[identifier].expression;
825 bfn = true;
826 } else if (GDScriptLanguage::get_singleton()->get_global_map().has(identifier)) {
827 //check from constants
828 ConstantNode *constant = alloc_node<ConstantNode>();
829 constant->value = GDScriptLanguage::get_singleton()->get_global_array()[GDScriptLanguage::get_singleton()->get_global_map()[identifier]];
830 constant->datatype = _type_from_variant(constant->value);
831 constant->line = id_line;
832 expr = constant;
833 bfn = true;
834 }
835
836 if (!bfn && GDScriptLanguage::get_singleton()->get_named_globals_map().has(identifier)) {
837 //check from singletons
838 ConstantNode *constant = alloc_node<ConstantNode>();
839 constant->value = GDScriptLanguage::get_singleton()->get_named_globals_map()[identifier];
840 expr = constant;
841 bfn = true;
842 }
843
844 if (!dependencies_only) {
845 if (!bfn && ScriptServer::is_global_class(identifier)) {
846 Ref<Script> scr = ResourceLoader::load(ScriptServer::get_global_class_path(identifier));
847 if (scr.is_valid() && scr->is_valid()) {
848 ConstantNode *constant = alloc_node<ConstantNode>();
849 constant->value = scr;
850 expr = constant;
851 bfn = true;
852 }
853 }
854
855 // Check parents for the constant
856 if (!bfn) {
857 // Using current_class instead of cln here, since cln is const*
858 _determine_inheritance(current_class, false);
859 if (cln->base_type.has_type && cln->base_type.kind == DataType::GDSCRIPT && cln->base_type.script_type->is_valid()) {
860 Map<StringName, Variant> parent_constants;
861 current_class->base_type.script_type->get_constants(&parent_constants);
862 if (parent_constants.has(identifier)) {
863 ConstantNode *constant = alloc_node<ConstantNode>();
864 constant->value = parent_constants[identifier];
865 expr = constant;
866 bfn = true;
867 }
868 }
869 }
870 }
871 }
872
873 if (!bfn) {
874 #ifdef DEBUG_ENABLED
875 if (current_function) {
876 int arg_idx = current_function->arguments.find(identifier);
877 if (arg_idx != -1) {
878 switch (tokenizer->get_token()) {
879 case GDScriptTokenizer::TK_OP_ASSIGN_ADD:
880 case GDScriptTokenizer::TK_OP_ASSIGN_BIT_AND:
881 case GDScriptTokenizer::TK_OP_ASSIGN_BIT_OR:
882 case GDScriptTokenizer::TK_OP_ASSIGN_BIT_XOR:
883 case GDScriptTokenizer::TK_OP_ASSIGN_DIV:
884 case GDScriptTokenizer::TK_OP_ASSIGN_MOD:
885 case GDScriptTokenizer::TK_OP_ASSIGN_MUL:
886 case GDScriptTokenizer::TK_OP_ASSIGN_SHIFT_LEFT:
887 case GDScriptTokenizer::TK_OP_ASSIGN_SHIFT_RIGHT:
888 case GDScriptTokenizer::TK_OP_ASSIGN_SUB:
889 case GDScriptTokenizer::TK_OP_ASSIGN: {
890 // Assignment is not really usage
891 } break;
892 default: {
893 current_function->arguments_usage.write[arg_idx] = current_function->arguments_usage[arg_idx] + 1;
894 }
895 }
896 }
897 }
898 #endif // DEBUG_ENABLED
899 IdentifierNode *id = alloc_node<IdentifierNode>();
900 id->name = identifier;
901 id->line = id_line;
902 expr = id;
903 }
904
905 } else if (tokenizer->get_token() == GDScriptTokenizer::TK_OP_ADD || tokenizer->get_token() == GDScriptTokenizer::TK_OP_SUB || tokenizer->get_token() == GDScriptTokenizer::TK_OP_NOT || tokenizer->get_token() == GDScriptTokenizer::TK_OP_BIT_INVERT) {
906
907 //single prefix operators like !expr +expr -expr ++expr --expr
908 alloc_node<OperatorNode>();
909 Expression e;
910 e.is_op = true;
911
912 switch (tokenizer->get_token()) {
913 case GDScriptTokenizer::TK_OP_ADD: e.op = OperatorNode::OP_POS; break;
914 case GDScriptTokenizer::TK_OP_SUB: e.op = OperatorNode::OP_NEG; break;
915 case GDScriptTokenizer::TK_OP_NOT: e.op = OperatorNode::OP_NOT; break;
916 case GDScriptTokenizer::TK_OP_BIT_INVERT: e.op = OperatorNode::OP_BIT_INVERT; break;
917 default: {
918 }
919 }
920
921 tokenizer->advance();
922
923 if (e.op != OperatorNode::OP_NOT && tokenizer->get_token() == GDScriptTokenizer::TK_OP_NOT) {
924 _set_error("Misplaced 'not'.");
925 return NULL;
926 }
927
928 expression.push_back(e);
929 continue; //only exception, must continue...
930
931 /*
932 Node *subexpr=_parse_expression(op,p_static);
933 if (!subexpr)
934 return NULL;
935 op->arguments.push_back(subexpr);
936 expr=op;*/
937
938 } else if (tokenizer->get_token() == GDScriptTokenizer::TK_PR_IS && tokenizer->get_token(1) == GDScriptTokenizer::TK_BUILT_IN_TYPE) {
939 // 'is' operator with built-in type
940 if (!expr) {
941 _set_error("Expected identifier before 'is' operator");
942 return NULL;
943 }
944 OperatorNode *op = alloc_node<OperatorNode>();
945 op->op = OperatorNode::OP_IS_BUILTIN;
946 op->arguments.push_back(expr);
947
948 tokenizer->advance();
949
950 TypeNode *tn = alloc_node<TypeNode>();
951 tn->vtype = tokenizer->get_token_type();
952 op->arguments.push_back(tn);
953 tokenizer->advance();
954
955 expr = op;
956 } else if (tokenizer->get_token() == GDScriptTokenizer::TK_BRACKET_OPEN) {
957 // array
958 tokenizer->advance();
959
960 ArrayNode *arr = alloc_node<ArrayNode>();
961 bool expecting_comma = false;
962
963 while (true) {
964
965 if (tokenizer->get_token() == GDScriptTokenizer::TK_EOF) {
966
967 _set_error("Unterminated array");
968 return NULL;
969
970 } else if (tokenizer->get_token() == GDScriptTokenizer::TK_BRACKET_CLOSE) {
971 tokenizer->advance();
972 break;
973 } else if (tokenizer->get_token() == GDScriptTokenizer::TK_NEWLINE) {
974
975 tokenizer->advance(); //ignore newline
976 } else if (tokenizer->get_token() == GDScriptTokenizer::TK_COMMA) {
977 if (!expecting_comma) {
978 _set_error("expression or ']' expected");
979 return NULL;
980 }
981
982 expecting_comma = false;
983 tokenizer->advance(); //ignore newline
984 } else {
985 //parse expression
986 if (expecting_comma) {
987 _set_error("',' or ']' expected");
988 return NULL;
989 }
990 Node *n = _parse_expression(arr, p_static, p_allow_assign, p_parsing_constant);
991 if (!n)
992 return NULL;
993 arr->elements.push_back(n);
994 expecting_comma = true;
995 }
996 }
997
998 expr = arr;
999 } else if (tokenizer->get_token() == GDScriptTokenizer::TK_CURLY_BRACKET_OPEN) {
1000 // array
1001 tokenizer->advance();
1002
1003 DictionaryNode *dict = alloc_node<DictionaryNode>();
1004
1005 enum DictExpect {
1006
1007 DICT_EXPECT_KEY,
1008 DICT_EXPECT_COLON,
1009 DICT_EXPECT_VALUE,
1010 DICT_EXPECT_COMMA
1011
1012 };
1013
1014 Node *key = NULL;
1015 Set<Variant> keys;
1016
1017 DictExpect expecting = DICT_EXPECT_KEY;
1018
1019 while (true) {
1020
1021 if (tokenizer->get_token() == GDScriptTokenizer::TK_EOF) {
1022
1023 _set_error("Unterminated dictionary");
1024 return NULL;
1025
1026 } else if (tokenizer->get_token() == GDScriptTokenizer::TK_CURLY_BRACKET_CLOSE) {
1027
1028 if (expecting == DICT_EXPECT_COLON) {
1029 _set_error("':' expected");
1030 return NULL;
1031 }
1032 if (expecting == DICT_EXPECT_VALUE) {
1033 _set_error("value expected");
1034 return NULL;
1035 }
1036 tokenizer->advance();
1037 break;
1038 } else if (tokenizer->get_token() == GDScriptTokenizer::TK_NEWLINE) {
1039
1040 tokenizer->advance(); //ignore newline
1041 } else if (tokenizer->get_token() == GDScriptTokenizer::TK_COMMA) {
1042
1043 if (expecting == DICT_EXPECT_KEY) {
1044 _set_error("key or '}' expected");
1045 return NULL;
1046 }
1047 if (expecting == DICT_EXPECT_VALUE) {
1048 _set_error("value expected");
1049 return NULL;
1050 }
1051 if (expecting == DICT_EXPECT_COLON) {
1052 _set_error("':' expected");
1053 return NULL;
1054 }
1055
1056 expecting = DICT_EXPECT_KEY;
1057 tokenizer->advance(); //ignore newline
1058
1059 } else if (tokenizer->get_token() == GDScriptTokenizer::TK_COLON) {
1060
1061 if (expecting == DICT_EXPECT_KEY) {
1062 _set_error("key or '}' expected");
1063 return NULL;
1064 }
1065 if (expecting == DICT_EXPECT_VALUE) {
1066 _set_error("value expected");
1067 return NULL;
1068 }
1069 if (expecting == DICT_EXPECT_COMMA) {
1070 _set_error("',' or '}' expected");
1071 return NULL;
1072 }
1073
1074 expecting = DICT_EXPECT_VALUE;
1075 tokenizer->advance(); //ignore newline
1076 } else {
1077
1078 if (expecting == DICT_EXPECT_COMMA) {
1079 _set_error("',' or '}' expected");
1080 return NULL;
1081 }
1082 if (expecting == DICT_EXPECT_COLON) {
1083 _set_error("':' expected");
1084 return NULL;
1085 }
1086
1087 if (expecting == DICT_EXPECT_KEY) {
1088
1089 if (tokenizer->is_token_literal() && tokenizer->get_token(1) == GDScriptTokenizer::TK_OP_ASSIGN) {
1090 // We check with is_token_literal, as this allows us to use match/sync/etc. as a name
1091 //lua style identifier, easier to write
1092 ConstantNode *cn = alloc_node<ConstantNode>();
1093 cn->value = tokenizer->get_token_literal();
1094 cn->datatype = _type_from_variant(cn->value);
1095 key = cn;
1096 tokenizer->advance(2);
1097 expecting = DICT_EXPECT_VALUE;
1098 } else {
1099 //python/js style more flexible
1100 key = _parse_expression(dict, p_static, p_allow_assign, p_parsing_constant);
1101 if (!key)
1102 return NULL;
1103 expecting = DICT_EXPECT_COLON;
1104 }
1105 }
1106
1107 if (expecting == DICT_EXPECT_VALUE) {
1108 Node *value = _parse_expression(dict, p_static, p_allow_assign, p_parsing_constant);
1109 if (!value)
1110 return NULL;
1111 expecting = DICT_EXPECT_COMMA;
1112
1113 if (key->type == GDScriptParser::Node::TYPE_CONSTANT) {
1114 Variant const &keyName = static_cast<const GDScriptParser::ConstantNode *>(key)->value;
1115
1116 if (keys.has(keyName)) {
1117 _set_error("Duplicate key found in Dictionary literal");
1118 return NULL;
1119 }
1120 keys.insert(keyName);
1121 }
1122
1123 DictionaryNode::Pair pair;
1124 pair.key = key;
1125 pair.value = value;
1126 dict->elements.push_back(pair);
1127 key = NULL;
1128 }
1129 }
1130 }
1131
1132 expr = dict;
1133
1134 } else if (tokenizer->get_token() == GDScriptTokenizer::TK_PERIOD && (tokenizer->is_token_literal(1) || tokenizer->get_token(1) == GDScriptTokenizer::TK_CURSOR)) {
1135 // We check with is_token_literal, as this allows us to use match/sync/etc. as a name
1136 // parent call
1137
1138 tokenizer->advance(); //goto identifier
1139 OperatorNode *op = alloc_node<OperatorNode>();
1140 op->op = OperatorNode::OP_PARENT_CALL;
1141
1142 /*SelfNode *self = alloc_node<SelfNode>();
1143 op->arguments.push_back(self);
1144 forbidden for now */
1145 StringName identifier;
1146 bool is_completion = _get_completable_identifier(COMPLETION_PARENT_FUNCTION, identifier) && for_completion;
1147
1148 IdentifierNode *id = alloc_node<IdentifierNode>();
1149 id->name = identifier;
1150 op->arguments.push_back(id);
1151
1152 if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_OPEN) {
1153 if (!is_completion) {
1154 _set_error("Expected '(' for parent function call.");
1155 return NULL;
1156 }
1157 } else {
1158 tokenizer->advance();
1159 if (!_parse_arguments(op, op->arguments, p_static, false, p_parsing_constant)) {
1160 return NULL;
1161 }
1162 }
1163
1164 expr = op;
1165
1166 } else if (tokenizer->get_token() == GDScriptTokenizer::TK_BUILT_IN_TYPE && expression.size() > 0 && expression[expression.size() - 1].is_op && expression[expression.size() - 1].op == OperatorNode::OP_IS) {
1167 Expression e = expression[expression.size() - 1];
1168 e.op = OperatorNode::OP_IS_BUILTIN;
1169 expression.write[expression.size() - 1] = e;
1170
1171 TypeNode *tn = alloc_node<TypeNode>();
1172 tn->vtype = tokenizer->get_token_type();
1173 expr = tn;
1174 tokenizer->advance();
1175 } else {
1176
1177 //find list [ or find dictionary {
1178 _set_error("Error parsing expression, misplaced: " + String(tokenizer->get_token_name(tokenizer->get_token())));
1179 return NULL; //nothing
1180 }
1181
1182 ERR_FAIL_COND_V_MSG(!expr, NULL, "GDScriptParser bug, couldn't figure out what expression is.");
1183
1184 /******************/
1185 /* Parse Indexing */
1186 /******************/
1187
1188 while (true) {
1189
1190 //expressions can be indexed any number of times
1191
1192 if (tokenizer->get_token() == GDScriptTokenizer::TK_PERIOD) {
1193
1194 //indexing using "."
1195
1196 if (tokenizer->get_token(1) != GDScriptTokenizer::TK_CURSOR && !tokenizer->is_token_literal(1)) {
1197 // We check with is_token_literal, as this allows us to use match/sync/etc. as a name
1198 _set_error("Expected identifier as member");
1199 return NULL;
1200 } else if (tokenizer->get_token(2) == GDScriptTokenizer::TK_PARENTHESIS_OPEN) {
1201 //call!!
1202 OperatorNode *op = alloc_node<OperatorNode>();
1203 op->op = OperatorNode::OP_CALL;
1204
1205 tokenizer->advance();
1206
1207 IdentifierNode *id = alloc_node<IdentifierNode>();
1208 StringName identifier;
1209 if (_get_completable_identifier(COMPLETION_METHOD, identifier)) {
1210 completion_node = op;
1211 //indexing stuff
1212 }
1213
1214 id->name = identifier;
1215
1216 op->arguments.push_back(expr); // call what
1217 op->arguments.push_back(id); // call func
1218 //get arguments
1219 tokenizer->advance(1);
1220 if (tokenizer->get_token() == GDScriptTokenizer::TK_CURSOR) {
1221 _make_completable_call(0);
1222 completion_node = op;
1223 }
1224 if (!_parse_arguments(op, op->arguments, p_static, true, p_parsing_constant))
1225 return NULL;
1226 expr = op;
1227
1228 } else {
1229 //simple indexing!
1230
1231 OperatorNode *op = alloc_node<OperatorNode>();
1232 op->op = OperatorNode::OP_INDEX_NAMED;
1233 tokenizer->advance();
1234
1235 StringName identifier;
1236 if (_get_completable_identifier(COMPLETION_INDEX, identifier)) {
1237
1238 if (identifier == StringName()) {
1239 identifier = "@temp"; //so it parses alright
1240 }
1241 completion_node = op;
1242
1243 //indexing stuff
1244 }
1245
1246 IdentifierNode *id = alloc_node<IdentifierNode>();
1247 id->name = identifier;
1248
1249 op->arguments.push_back(expr);
1250 op->arguments.push_back(id);
1251
1252 expr = op;
1253 }
1254
1255 } else if (tokenizer->get_token() == GDScriptTokenizer::TK_BRACKET_OPEN) {
1256 //indexing using "[]"
1257 OperatorNode *op = alloc_node<OperatorNode>();
1258 op->op = OperatorNode::OP_INDEX;
1259
1260 tokenizer->advance(1);
1261
1262 Node *subexpr = _parse_expression(op, p_static, p_allow_assign, p_parsing_constant);
1263 if (!subexpr) {
1264 return NULL;
1265 }
1266
1267 if (tokenizer->get_token() != GDScriptTokenizer::TK_BRACKET_CLOSE) {
1268 _set_error("Expected ']'");
1269 return NULL;
1270 }
1271
1272 op->arguments.push_back(expr);
1273 op->arguments.push_back(subexpr);
1274 tokenizer->advance(1);
1275 expr = op;
1276
1277 } else
1278 break;
1279 }
1280
1281 /*****************/
1282 /* Parse Casting */
1283 /*****************/
1284
1285 bool has_casting = expr->type == Node::TYPE_CAST;
1286 if (tokenizer->get_token() == GDScriptTokenizer::TK_PR_AS) {
1287 if (has_casting) {
1288 _set_error("Unexpected 'as'.");
1289 return NULL;
1290 }
1291 CastNode *cn = alloc_node<CastNode>();
1292 if (!_parse_type(cn->cast_type)) {
1293 _set_error("Expected type after 'as'.");
1294 return NULL;
1295 }
1296 has_casting = true;
1297 cn->source_node = expr;
1298 expr = cn;
1299 }
1300
1301 /******************/
1302 /* Parse Operator */
1303 /******************/
1304
1305 if (parenthesis > 0) {
1306 //remove empty space (only allowed if inside parenthesis
1307 while (tokenizer->get_token() == GDScriptTokenizer::TK_NEWLINE) {
1308 tokenizer->advance();
1309 }
1310 }
1311
1312 Expression e;
1313 e.is_op = false;
1314 e.node = expr;
1315 expression.push_back(e);
1316
1317 // determine which operator is next
1318
1319 OperatorNode::Operator op;
1320 bool valid = true;
1321
1322 //assign, if allowed is only allowed on the first operator
1323 #define _VALIDATE_ASSIGN \
1324 if (!p_allow_assign || has_casting) { \
1325 _set_error("Unexpected assign."); \
1326 return NULL; \
1327 } \
1328 p_allow_assign = false;
1329
1330 switch (tokenizer->get_token()) { //see operator
1331
1332 case GDScriptTokenizer::TK_OP_IN: op = OperatorNode::OP_IN; break;
1333 case GDScriptTokenizer::TK_OP_EQUAL: op = OperatorNode::OP_EQUAL; break;
1334 case GDScriptTokenizer::TK_OP_NOT_EQUAL: op = OperatorNode::OP_NOT_EQUAL; break;
1335 case GDScriptTokenizer::TK_OP_LESS: op = OperatorNode::OP_LESS; break;
1336 case GDScriptTokenizer::TK_OP_LESS_EQUAL: op = OperatorNode::OP_LESS_EQUAL; break;
1337 case GDScriptTokenizer::TK_OP_GREATER: op = OperatorNode::OP_GREATER; break;
1338 case GDScriptTokenizer::TK_OP_GREATER_EQUAL: op = OperatorNode::OP_GREATER_EQUAL; break;
1339 case GDScriptTokenizer::TK_OP_AND: op = OperatorNode::OP_AND; break;
1340 case GDScriptTokenizer::TK_OP_OR: op = OperatorNode::OP_OR; break;
1341 case GDScriptTokenizer::TK_OP_ADD: op = OperatorNode::OP_ADD; break;
1342 case GDScriptTokenizer::TK_OP_SUB: op = OperatorNode::OP_SUB; break;
1343 case GDScriptTokenizer::TK_OP_MUL: op = OperatorNode::OP_MUL; break;
1344 case GDScriptTokenizer::TK_OP_DIV: op = OperatorNode::OP_DIV; break;
1345 case GDScriptTokenizer::TK_OP_MOD:
1346 op = OperatorNode::OP_MOD;
1347 break;
1348 //case GDScriptTokenizer::TK_OP_NEG: op=OperatorNode::OP_NEG ; break;
1349 case GDScriptTokenizer::TK_OP_SHIFT_LEFT: op = OperatorNode::OP_SHIFT_LEFT; break;
1350 case GDScriptTokenizer::TK_OP_SHIFT_RIGHT: op = OperatorNode::OP_SHIFT_RIGHT; break;
1351 case GDScriptTokenizer::TK_OP_ASSIGN: {
1352 _VALIDATE_ASSIGN op = OperatorNode::OP_ASSIGN;
1353
1354 if (tokenizer->get_token(1) == GDScriptTokenizer::TK_CURSOR) {
1355 //code complete assignment
1356 completion_type = COMPLETION_ASSIGN;
1357 completion_node = expr;
1358 completion_class = current_class;
1359 completion_function = current_function;
1360 completion_line = tokenizer->get_token_line();
1361 completion_block = current_block;
1362 completion_found = true;
1363 tokenizer->advance();
1364 }
1365
1366 } break;
1367 case GDScriptTokenizer::TK_OP_ASSIGN_ADD: _VALIDATE_ASSIGN op = OperatorNode::OP_ASSIGN_ADD; break;
1368 case GDScriptTokenizer::TK_OP_ASSIGN_SUB: _VALIDATE_ASSIGN op = OperatorNode::OP_ASSIGN_SUB; break;
1369 case GDScriptTokenizer::TK_OP_ASSIGN_MUL: _VALIDATE_ASSIGN op = OperatorNode::OP_ASSIGN_MUL; break;
1370 case GDScriptTokenizer::TK_OP_ASSIGN_DIV: _VALIDATE_ASSIGN op = OperatorNode::OP_ASSIGN_DIV; break;
1371 case GDScriptTokenizer::TK_OP_ASSIGN_MOD: _VALIDATE_ASSIGN op = OperatorNode::OP_ASSIGN_MOD; break;
1372 case GDScriptTokenizer::TK_OP_ASSIGN_SHIFT_LEFT: _VALIDATE_ASSIGN op = OperatorNode::OP_ASSIGN_SHIFT_LEFT; break;
1373 case GDScriptTokenizer::TK_OP_ASSIGN_SHIFT_RIGHT: _VALIDATE_ASSIGN op = OperatorNode::OP_ASSIGN_SHIFT_RIGHT; break;
1374 case GDScriptTokenizer::TK_OP_ASSIGN_BIT_AND: _VALIDATE_ASSIGN op = OperatorNode::OP_ASSIGN_BIT_AND; break;
1375 case GDScriptTokenizer::TK_OP_ASSIGN_BIT_OR: _VALIDATE_ASSIGN op = OperatorNode::OP_ASSIGN_BIT_OR; break;
1376 case GDScriptTokenizer::TK_OP_ASSIGN_BIT_XOR: _VALIDATE_ASSIGN op = OperatorNode::OP_ASSIGN_BIT_XOR; break;
1377 case GDScriptTokenizer::TK_OP_BIT_AND: op = OperatorNode::OP_BIT_AND; break;
1378 case GDScriptTokenizer::TK_OP_BIT_OR: op = OperatorNode::OP_BIT_OR; break;
1379 case GDScriptTokenizer::TK_OP_BIT_XOR: op = OperatorNode::OP_BIT_XOR; break;
1380 case GDScriptTokenizer::TK_PR_IS: op = OperatorNode::OP_IS; break;
1381 case GDScriptTokenizer::TK_CF_IF: op = OperatorNode::OP_TERNARY_IF; break;
1382 case GDScriptTokenizer::TK_CF_ELSE: op = OperatorNode::OP_TERNARY_ELSE; break;
1383 default: valid = false; break;
1384 }
1385
1386 if (valid) {
1387 e.is_op = true;
1388 e.op = op;
1389 expression.push_back(e);
1390 tokenizer->advance();
1391 } else {
1392 break;
1393 }
1394 }
1395
1396 /* Reduce the set set of expressions and place them in an operator tree, respecting precedence */
1397
1398 while (expression.size() > 1) {
1399
1400 int next_op = -1;
1401 int min_priority = 0xFFFFF;
1402 bool is_unary = false;
1403 bool is_ternary = false;
1404
1405 for (int i = 0; i < expression.size(); i++) {
1406
1407 if (!expression[i].is_op) {
1408
1409 continue;
1410 }
1411
1412 int priority;
1413
1414 bool unary = false;
1415 bool ternary = false;
1416 bool error = false;
1417 bool right_to_left = false;
1418
1419 switch (expression[i].op) {
1420
1421 case OperatorNode::OP_IS:
1422 case OperatorNode::OP_IS_BUILTIN:
1423 priority = -1;
1424 break; //before anything
1425
1426 case OperatorNode::OP_BIT_INVERT:
1427 priority = 0;
1428 unary = true;
1429 break;
1430 case OperatorNode::OP_NEG:
1431 case OperatorNode::OP_POS:
1432 priority = 1;
1433 unary = true;
1434 break;
1435
1436 case OperatorNode::OP_MUL: priority = 2; break;
1437 case OperatorNode::OP_DIV: priority = 2; break;
1438 case OperatorNode::OP_MOD: priority = 2; break;
1439
1440 case OperatorNode::OP_ADD: priority = 3; break;
1441 case OperatorNode::OP_SUB: priority = 3; break;
1442
1443 case OperatorNode::OP_SHIFT_LEFT: priority = 4; break;
1444 case OperatorNode::OP_SHIFT_RIGHT: priority = 4; break;
1445
1446 case OperatorNode::OP_BIT_AND: priority = 5; break;
1447 case OperatorNode::OP_BIT_XOR: priority = 6; break;
1448 case OperatorNode::OP_BIT_OR: priority = 7; break;
1449
1450 case OperatorNode::OP_LESS: priority = 8; break;
1451 case OperatorNode::OP_LESS_EQUAL: priority = 8; break;
1452 case OperatorNode::OP_GREATER: priority = 8; break;
1453 case OperatorNode::OP_GREATER_EQUAL: priority = 8; break;
1454
1455 case OperatorNode::OP_EQUAL: priority = 8; break;
1456 case OperatorNode::OP_NOT_EQUAL: priority = 8; break;
1457
1458 case OperatorNode::OP_IN: priority = 10; break;
1459
1460 case OperatorNode::OP_NOT:
1461 priority = 11;
1462 unary = true;
1463 break;
1464 case OperatorNode::OP_AND: priority = 12; break;
1465 case OperatorNode::OP_OR: priority = 13; break;
1466
1467 case OperatorNode::OP_TERNARY_IF:
1468 priority = 14;
1469 ternary = true;
1470 right_to_left = true;
1471 break;
1472 case OperatorNode::OP_TERNARY_ELSE:
1473 priority = 14;
1474 error = true;
1475 // Rigth-to-left should be false in this case, otherwise it would always error.
1476 break;
1477
1478 case OperatorNode::OP_ASSIGN: priority = 15; break;
1479 case OperatorNode::OP_ASSIGN_ADD: priority = 15; break;
1480 case OperatorNode::OP_ASSIGN_SUB: priority = 15; break;
1481 case OperatorNode::OP_ASSIGN_MUL: priority = 15; break;
1482 case OperatorNode::OP_ASSIGN_DIV: priority = 15; break;
1483 case OperatorNode::OP_ASSIGN_MOD: priority = 15; break;
1484 case OperatorNode::OP_ASSIGN_SHIFT_LEFT: priority = 15; break;
1485 case OperatorNode::OP_ASSIGN_SHIFT_RIGHT: priority = 15; break;
1486 case OperatorNode::OP_ASSIGN_BIT_AND: priority = 15; break;
1487 case OperatorNode::OP_ASSIGN_BIT_OR: priority = 15; break;
1488 case OperatorNode::OP_ASSIGN_BIT_XOR: priority = 15; break;
1489
1490 default: {
1491 _set_error("GDScriptParser bug, invalid operator in expression: " + itos(expression[i].op));
1492 return NULL;
1493 }
1494 }
1495
1496 if (priority < min_priority || (right_to_left && priority == min_priority)) {
1497 // < is used for left to right (default)
1498 // <= is used for right to left
1499 if (error) {
1500 _set_error("Unexpected operator");
1501 return NULL;
1502 }
1503 next_op = i;
1504 min_priority = priority;
1505 is_unary = unary;
1506 is_ternary = ternary;
1507 }
1508 }
1509
1510 if (next_op == -1) {
1511
1512 _set_error("Yet another parser bug....");
1513 ERR_FAIL_V(NULL);
1514 }
1515
1516 // OK! create operator..
1517 if (is_unary) {
1518
1519 int expr_pos = next_op;
1520 while (expression[expr_pos].is_op) {
1521
1522 expr_pos++;
1523 if (expr_pos == expression.size()) {
1524 //can happen..
1525 _set_error("Unexpected end of expression...");
1526 return NULL;
1527 }
1528 }
1529
1530 //consecutively do unary opeators
1531 for (int i = expr_pos - 1; i >= next_op; i--) {
1532
1533 OperatorNode *op = alloc_node<OperatorNode>();
1534 op->op = expression[i].op;
1535 op->arguments.push_back(expression[i + 1].node);
1536 op->line = op_line; //line might have been changed from a \n
1537 expression.write[i].is_op = false;
1538 expression.write[i].node = op;
1539 expression.remove(i + 1);
1540 }
1541
1542 } else if (is_ternary) {
1543 if (next_op < 1 || next_op >= (expression.size() - 1)) {
1544 _set_error("Parser bug...");
1545 ERR_FAIL_V(NULL);
1546 }
1547
1548 if (next_op >= (expression.size() - 2) || expression[next_op + 2].op != OperatorNode::OP_TERNARY_ELSE) {
1549 _set_error("Expected else after ternary if.");
1550 return NULL;
1551 }
1552 if (next_op >= (expression.size() - 3)) {
1553 _set_error("Expected value after ternary else.");
1554 return NULL;
1555 }
1556
1557 OperatorNode *op = alloc_node<OperatorNode>();
1558 op->op = expression[next_op].op;
1559 op->line = op_line; //line might have been changed from a \n
1560
1561 if (expression[next_op - 1].is_op) {
1562
1563 _set_error("Parser bug...");
1564 ERR_FAIL_V(NULL);
1565 }
1566
1567 if (expression[next_op + 1].is_op) {
1568 // this is not invalid and can really appear
1569 // but it becomes invalid anyway because no binary op
1570 // can be followed by a unary op in a valid combination,
1571 // due to how precedence works, unaries will always disappear first
1572
1573 _set_error("Unexpected two consecutive operators after ternary if.");
1574 return NULL;
1575 }
1576
1577 if (expression[next_op + 3].is_op) {
1578 // this is not invalid and can really appear
1579 // but it becomes invalid anyway because no binary op
1580 // can be followed by a unary op in a valid combination,
1581 // due to how precedence works, unaries will always disappear first
1582
1583 _set_error("Unexpected two consecutive operators after ternary else.");
1584 return NULL;
1585 }
1586
1587 op->arguments.push_back(expression[next_op + 1].node); //next expression goes as first
1588 op->arguments.push_back(expression[next_op - 1].node); //left expression goes as when-true
1589 op->arguments.push_back(expression[next_op + 3].node); //expression after next goes as when-false
1590
1591 //replace all 3 nodes by this operator and make it an expression
1592 expression.write[next_op - 1].node = op;
1593 expression.remove(next_op);
1594 expression.remove(next_op);
1595 expression.remove(next_op);
1596 expression.remove(next_op);
1597 } else {
1598
1599 if (next_op < 1 || next_op >= (expression.size() - 1)) {
1600 _set_error("Parser bug...");
1601 ERR_FAIL_V(NULL);
1602 }
1603
1604 OperatorNode *op = alloc_node<OperatorNode>();
1605 op->op = expression[next_op].op;
1606 op->line = op_line; //line might have been changed from a \n
1607
1608 if (expression[next_op - 1].is_op) {
1609
1610 _set_error("Parser bug...");
1611 ERR_FAIL_V(NULL);
1612 }
1613
1614 if (expression[next_op + 1].is_op) {
1615 // this is not invalid and can really appear
1616 // but it becomes invalid anyway because no binary op
1617 // can be followed by a unary op in a valid combination,
1618 // due to how precedence works, unaries will always disappear first
1619
1620 _set_error("Unexpected two consecutive operators.");
1621 return NULL;
1622 }
1623
1624 op->arguments.push_back(expression[next_op - 1].node); //expression goes as left
1625 op->arguments.push_back(expression[next_op + 1].node); //next expression goes as right
1626
1627 //replace all 3 nodes by this operator and make it an expression
1628 expression.write[next_op - 1].node = op;
1629 expression.remove(next_op);
1630 expression.remove(next_op);
1631 }
1632 }
1633
1634 return expression[0].node;
1635 }
1636
_reduce_expression(Node * p_node,bool p_to_const)1637 GDScriptParser::Node *GDScriptParser::_reduce_expression(Node *p_node, bool p_to_const) {
1638
1639 switch (p_node->type) {
1640
1641 case Node::TYPE_BUILT_IN_FUNCTION: {
1642 //many may probably be optimizable
1643 return p_node;
1644 } break;
1645 case Node::TYPE_ARRAY: {
1646
1647 ArrayNode *an = static_cast<ArrayNode *>(p_node);
1648 bool all_constants = true;
1649
1650 for (int i = 0; i < an->elements.size(); i++) {
1651
1652 an->elements.write[i] = _reduce_expression(an->elements[i], p_to_const);
1653 if (an->elements[i]->type != Node::TYPE_CONSTANT)
1654 all_constants = false;
1655 }
1656
1657 if (all_constants && p_to_const) {
1658 //reduce constant array expression
1659
1660 ConstantNode *cn = alloc_node<ConstantNode>();
1661 Array arr;
1662 arr.resize(an->elements.size());
1663 for (int i = 0; i < an->elements.size(); i++) {
1664 ConstantNode *acn = static_cast<ConstantNode *>(an->elements[i]);
1665 arr[i] = acn->value;
1666 }
1667 cn->value = arr;
1668 cn->datatype = _type_from_variant(cn->value);
1669 return cn;
1670 }
1671
1672 return an;
1673
1674 } break;
1675 case Node::TYPE_DICTIONARY: {
1676
1677 DictionaryNode *dn = static_cast<DictionaryNode *>(p_node);
1678 bool all_constants = true;
1679
1680 for (int i = 0; i < dn->elements.size(); i++) {
1681
1682 dn->elements.write[i].key = _reduce_expression(dn->elements[i].key, p_to_const);
1683 if (dn->elements[i].key->type != Node::TYPE_CONSTANT)
1684 all_constants = false;
1685 dn->elements.write[i].value = _reduce_expression(dn->elements[i].value, p_to_const);
1686 if (dn->elements[i].value->type != Node::TYPE_CONSTANT)
1687 all_constants = false;
1688 }
1689
1690 if (all_constants && p_to_const) {
1691 //reduce constant array expression
1692
1693 ConstantNode *cn = alloc_node<ConstantNode>();
1694 Dictionary dict;
1695 for (int i = 0; i < dn->elements.size(); i++) {
1696 ConstantNode *key_c = static_cast<ConstantNode *>(dn->elements[i].key);
1697 ConstantNode *value_c = static_cast<ConstantNode *>(dn->elements[i].value);
1698
1699 dict[key_c->value] = value_c->value;
1700 }
1701 cn->value = dict;
1702 cn->datatype = _type_from_variant(cn->value);
1703 return cn;
1704 }
1705
1706 return dn;
1707
1708 } break;
1709 case Node::TYPE_OPERATOR: {
1710
1711 OperatorNode *op = static_cast<OperatorNode *>(p_node);
1712
1713 bool all_constants = true;
1714 int last_not_constant = -1;
1715
1716 for (int i = 0; i < op->arguments.size(); i++) {
1717
1718 op->arguments.write[i] = _reduce_expression(op->arguments[i], p_to_const);
1719 if (op->arguments[i]->type != Node::TYPE_CONSTANT) {
1720 all_constants = false;
1721 last_not_constant = i;
1722 }
1723 }
1724
1725 if (op->op == OperatorNode::OP_IS) {
1726 //nothing much
1727 return op;
1728 }
1729 if (op->op == OperatorNode::OP_PARENT_CALL) {
1730 //nothing much
1731 return op;
1732
1733 } else if (op->op == OperatorNode::OP_CALL) {
1734 //can reduce base type constructors
1735 if ((op->arguments[0]->type == Node::TYPE_TYPE || (op->arguments[0]->type == Node::TYPE_BUILT_IN_FUNCTION && GDScriptFunctions::is_deterministic(static_cast<BuiltInFunctionNode *>(op->arguments[0])->function))) && last_not_constant == 0) {
1736
1737 //native type constructor or intrinsic function
1738 const Variant **vptr = NULL;
1739 Vector<Variant *> ptrs;
1740 if (op->arguments.size() > 1) {
1741
1742 ptrs.resize(op->arguments.size() - 1);
1743 for (int i = 0; i < ptrs.size(); i++) {
1744
1745 ConstantNode *cn = static_cast<ConstantNode *>(op->arguments[i + 1]);
1746 ptrs.write[i] = &cn->value;
1747 }
1748
1749 vptr = (const Variant **)&ptrs[0];
1750 }
1751
1752 Variant::CallError ce;
1753 Variant v;
1754
1755 if (op->arguments[0]->type == Node::TYPE_TYPE) {
1756 TypeNode *tn = static_cast<TypeNode *>(op->arguments[0]);
1757 v = Variant::construct(tn->vtype, vptr, ptrs.size(), ce);
1758
1759 } else {
1760 GDScriptFunctions::Function func = static_cast<BuiltInFunctionNode *>(op->arguments[0])->function;
1761 GDScriptFunctions::call(func, vptr, ptrs.size(), v, ce);
1762 }
1763
1764 if (ce.error != Variant::CallError::CALL_OK) {
1765
1766 String errwhere;
1767 if (op->arguments[0]->type == Node::TYPE_TYPE) {
1768 TypeNode *tn = static_cast<TypeNode *>(op->arguments[0]);
1769 errwhere = "'" + Variant::get_type_name(tn->vtype) + "' constructor";
1770
1771 } else {
1772 GDScriptFunctions::Function func = static_cast<BuiltInFunctionNode *>(op->arguments[0])->function;
1773 errwhere = String("'") + GDScriptFunctions::get_func_name(func) + "' intrinsic function";
1774 }
1775
1776 switch (ce.error) {
1777
1778 case Variant::CallError::CALL_ERROR_INVALID_ARGUMENT: {
1779
1780 _set_error("Invalid argument (#" + itos(ce.argument + 1) + ") for " + errwhere + ".");
1781
1782 } break;
1783 case Variant::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS: {
1784
1785 _set_error("Too many arguments for " + errwhere + ".");
1786 } break;
1787 case Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS: {
1788
1789 _set_error("Too few arguments for " + errwhere + ".");
1790 } break;
1791 default: {
1792 _set_error("Invalid arguments for " + errwhere + ".");
1793
1794 } break;
1795 }
1796
1797 error_line = op->line;
1798
1799 return p_node;
1800 }
1801
1802 ConstantNode *cn = alloc_node<ConstantNode>();
1803 cn->value = v;
1804 cn->datatype = _type_from_variant(v);
1805 return cn;
1806 }
1807
1808 return op; //don't reduce yet
1809
1810 } else if (op->op == OperatorNode::OP_YIELD) {
1811 return op;
1812
1813 } else if (op->op == OperatorNode::OP_INDEX) {
1814 //can reduce indices into constant arrays or dictionaries
1815
1816 if (all_constants) {
1817
1818 ConstantNode *ca = static_cast<ConstantNode *>(op->arguments[0]);
1819 ConstantNode *cb = static_cast<ConstantNode *>(op->arguments[1]);
1820
1821 bool valid;
1822
1823 Variant v = ca->value.get(cb->value, &valid);
1824 if (!valid) {
1825 _set_error("invalid index in constant expression");
1826 error_line = op->line;
1827 return op;
1828 }
1829
1830 ConstantNode *cn = alloc_node<ConstantNode>();
1831 cn->value = v;
1832 cn->datatype = _type_from_variant(v);
1833 return cn;
1834 }
1835
1836 return op;
1837
1838 } else if (op->op == OperatorNode::OP_INDEX_NAMED) {
1839
1840 if (op->arguments[0]->type == Node::TYPE_CONSTANT && op->arguments[1]->type == Node::TYPE_IDENTIFIER) {
1841
1842 ConstantNode *ca = static_cast<ConstantNode *>(op->arguments[0]);
1843 IdentifierNode *ib = static_cast<IdentifierNode *>(op->arguments[1]);
1844
1845 bool valid;
1846 Variant v = ca->value.get_named(ib->name, &valid);
1847 if (!valid) {
1848 _set_error("invalid index '" + String(ib->name) + "' in constant expression");
1849 error_line = op->line;
1850 return op;
1851 }
1852
1853 ConstantNode *cn = alloc_node<ConstantNode>();
1854 cn->value = v;
1855 cn->datatype = _type_from_variant(v);
1856 return cn;
1857 }
1858
1859 return op;
1860 }
1861
1862 //validate assignment (don't assign to constant expression
1863 switch (op->op) {
1864
1865 case OperatorNode::OP_ASSIGN:
1866 case OperatorNode::OP_ASSIGN_ADD:
1867 case OperatorNode::OP_ASSIGN_SUB:
1868 case OperatorNode::OP_ASSIGN_MUL:
1869 case OperatorNode::OP_ASSIGN_DIV:
1870 case OperatorNode::OP_ASSIGN_MOD:
1871 case OperatorNode::OP_ASSIGN_SHIFT_LEFT:
1872 case OperatorNode::OP_ASSIGN_SHIFT_RIGHT:
1873 case OperatorNode::OP_ASSIGN_BIT_AND:
1874 case OperatorNode::OP_ASSIGN_BIT_OR:
1875 case OperatorNode::OP_ASSIGN_BIT_XOR: {
1876
1877 if (op->arguments[0]->type == Node::TYPE_CONSTANT) {
1878 _set_error("Can't assign to constant", tokenizer->get_token_line() - 1);
1879 error_line = op->line;
1880 return op;
1881 } else if (op->arguments[0]->type == Node::TYPE_SELF) {
1882 _set_error("Can't assign to self.", op->line);
1883 error_line = op->line;
1884 return op;
1885 }
1886
1887 if (op->arguments[0]->type == Node::TYPE_OPERATOR) {
1888 OperatorNode *on = static_cast<OperatorNode *>(op->arguments[0]);
1889 if (on->op != OperatorNode::OP_INDEX && on->op != OperatorNode::OP_INDEX_NAMED) {
1890 _set_error("Can't assign to an expression", tokenizer->get_token_line() - 1);
1891 error_line = op->line;
1892 return op;
1893 }
1894 }
1895
1896 } break;
1897 default: {
1898 break;
1899 }
1900 }
1901 //now se if all are constants
1902 if (!all_constants)
1903 return op; //nothing to reduce from here on
1904 #define _REDUCE_UNARY(m_vop) \
1905 bool valid = false; \
1906 Variant res; \
1907 Variant::evaluate(m_vop, static_cast<ConstantNode *>(op->arguments[0])->value, Variant(), res, valid); \
1908 if (!valid) { \
1909 _set_error("Invalid operand for unary operator"); \
1910 error_line = op->line; \
1911 return p_node; \
1912 } \
1913 ConstantNode *cn = alloc_node<ConstantNode>(); \
1914 cn->value = res; \
1915 cn->datatype = _type_from_variant(res); \
1916 return cn;
1917
1918 #define _REDUCE_BINARY(m_vop) \
1919 bool valid = false; \
1920 Variant res; \
1921 Variant::evaluate(m_vop, static_cast<ConstantNode *>(op->arguments[0])->value, static_cast<ConstantNode *>(op->arguments[1])->value, res, valid); \
1922 if (!valid) { \
1923 _set_error("Invalid operands for operator"); \
1924 error_line = op->line; \
1925 return p_node; \
1926 } \
1927 ConstantNode *cn = alloc_node<ConstantNode>(); \
1928 cn->value = res; \
1929 cn->datatype = _type_from_variant(res); \
1930 return cn;
1931
1932 switch (op->op) {
1933
1934 //unary operators
1935 case OperatorNode::OP_NEG: {
1936 _REDUCE_UNARY(Variant::OP_NEGATE);
1937 } break;
1938 case OperatorNode::OP_POS: {
1939 _REDUCE_UNARY(Variant::OP_POSITIVE);
1940 } break;
1941 case OperatorNode::OP_NOT: {
1942 _REDUCE_UNARY(Variant::OP_NOT);
1943 } break;
1944 case OperatorNode::OP_BIT_INVERT: {
1945 _REDUCE_UNARY(Variant::OP_BIT_NEGATE);
1946 } break;
1947 //binary operators (in precedence order)
1948 case OperatorNode::OP_IN: {
1949 _REDUCE_BINARY(Variant::OP_IN);
1950 } break;
1951 case OperatorNode::OP_EQUAL: {
1952 _REDUCE_BINARY(Variant::OP_EQUAL);
1953 } break;
1954 case OperatorNode::OP_NOT_EQUAL: {
1955 _REDUCE_BINARY(Variant::OP_NOT_EQUAL);
1956 } break;
1957 case OperatorNode::OP_LESS: {
1958 _REDUCE_BINARY(Variant::OP_LESS);
1959 } break;
1960 case OperatorNode::OP_LESS_EQUAL: {
1961 _REDUCE_BINARY(Variant::OP_LESS_EQUAL);
1962 } break;
1963 case OperatorNode::OP_GREATER: {
1964 _REDUCE_BINARY(Variant::OP_GREATER);
1965 } break;
1966 case OperatorNode::OP_GREATER_EQUAL: {
1967 _REDUCE_BINARY(Variant::OP_GREATER_EQUAL);
1968 } break;
1969 case OperatorNode::OP_AND: {
1970 _REDUCE_BINARY(Variant::OP_AND);
1971 } break;
1972 case OperatorNode::OP_OR: {
1973 _REDUCE_BINARY(Variant::OP_OR);
1974 } break;
1975 case OperatorNode::OP_ADD: {
1976 _REDUCE_BINARY(Variant::OP_ADD);
1977 } break;
1978 case OperatorNode::OP_SUB: {
1979 _REDUCE_BINARY(Variant::OP_SUBTRACT);
1980 } break;
1981 case OperatorNode::OP_MUL: {
1982 _REDUCE_BINARY(Variant::OP_MULTIPLY);
1983 } break;
1984 case OperatorNode::OP_DIV: {
1985 _REDUCE_BINARY(Variant::OP_DIVIDE);
1986 } break;
1987 case OperatorNode::OP_MOD: {
1988 _REDUCE_BINARY(Variant::OP_MODULE);
1989 } break;
1990 case OperatorNode::OP_SHIFT_LEFT: {
1991 _REDUCE_BINARY(Variant::OP_SHIFT_LEFT);
1992 } break;
1993 case OperatorNode::OP_SHIFT_RIGHT: {
1994 _REDUCE_BINARY(Variant::OP_SHIFT_RIGHT);
1995 } break;
1996 case OperatorNode::OP_BIT_AND: {
1997 _REDUCE_BINARY(Variant::OP_BIT_AND);
1998 } break;
1999 case OperatorNode::OP_BIT_OR: {
2000 _REDUCE_BINARY(Variant::OP_BIT_OR);
2001 } break;
2002 case OperatorNode::OP_BIT_XOR: {
2003 _REDUCE_BINARY(Variant::OP_BIT_XOR);
2004 } break;
2005 case OperatorNode::OP_TERNARY_IF: {
2006 if (static_cast<ConstantNode *>(op->arguments[0])->value.booleanize()) {
2007 return op->arguments[1];
2008 } else {
2009 return op->arguments[2];
2010 }
2011 } break;
2012 default: {
2013 ERR_FAIL_V(op);
2014 }
2015 }
2016
2017 } break;
2018 default: {
2019 return p_node;
2020 } break;
2021 }
2022 }
2023
_parse_and_reduce_expression(Node * p_parent,bool p_static,bool p_reduce_const,bool p_allow_assign)2024 GDScriptParser::Node *GDScriptParser::_parse_and_reduce_expression(Node *p_parent, bool p_static, bool p_reduce_const, bool p_allow_assign) {
2025
2026 Node *expr = _parse_expression(p_parent, p_static, p_allow_assign, p_reduce_const);
2027 if (!expr || error_set)
2028 return NULL;
2029 expr = _reduce_expression(expr, p_reduce_const);
2030 if (!expr || error_set)
2031 return NULL;
2032 return expr;
2033 }
2034
_reduce_export_var_type(Variant & p_value,int p_line)2035 bool GDScriptParser::_reduce_export_var_type(Variant &p_value, int p_line) {
2036
2037 if (p_value.get_type() == Variant::ARRAY) {
2038 Array arr = p_value;
2039 for (int i = 0; i < arr.size(); i++) {
2040 if (!_reduce_export_var_type(arr[i], p_line)) return false;
2041 }
2042 return true;
2043 }
2044
2045 if (p_value.get_type() == Variant::DICTIONARY) {
2046 Dictionary dict = p_value;
2047 for (int i = 0; i < dict.size(); i++) {
2048 Variant value = dict.get_value_at_index(i);
2049 if (!_reduce_export_var_type(value, p_line)) return false;
2050 }
2051 return true;
2052 }
2053
2054 // validate type
2055 DataType type = _type_from_variant(p_value);
2056 if (type.kind == DataType::BUILTIN) {
2057 return true;
2058 } else if (type.kind == DataType::NATIVE) {
2059 if (ClassDB::is_parent_class(type.native_type, "Resource")) {
2060 return true;
2061 }
2062 }
2063 _set_error("Invalid export type. Only built-in and native resource types can be exported.", p_line);
2064 return false;
2065 }
2066
_recover_from_completion()2067 bool GDScriptParser::_recover_from_completion() {
2068
2069 if (!completion_found) {
2070 return false; //can't recover if no completion
2071 }
2072 //skip stuff until newline
2073 while (tokenizer->get_token() != GDScriptTokenizer::TK_NEWLINE && tokenizer->get_token() != GDScriptTokenizer::TK_EOF && tokenizer->get_token() != GDScriptTokenizer::TK_ERROR) {
2074 tokenizer->advance();
2075 }
2076 completion_found = false;
2077 error_set = false;
2078 if (tokenizer->get_token() == GDScriptTokenizer::TK_ERROR) {
2079 error_set = true;
2080 }
2081
2082 return true;
2083 }
2084
_parse_pattern(bool p_static)2085 GDScriptParser::PatternNode *GDScriptParser::_parse_pattern(bool p_static) {
2086
2087 PatternNode *pattern = alloc_node<PatternNode>();
2088
2089 GDScriptTokenizer::Token token = tokenizer->get_token();
2090 if (error_set)
2091 return NULL;
2092
2093 if (token == GDScriptTokenizer::TK_EOF) {
2094 return NULL;
2095 }
2096
2097 switch (token) {
2098 // array
2099 case GDScriptTokenizer::TK_BRACKET_OPEN: {
2100 tokenizer->advance();
2101 pattern->pt_type = GDScriptParser::PatternNode::PT_ARRAY;
2102 while (true) {
2103
2104 if (tokenizer->get_token() == GDScriptTokenizer::TK_BRACKET_CLOSE) {
2105 tokenizer->advance();
2106 break;
2107 }
2108
2109 if (tokenizer->get_token() == GDScriptTokenizer::TK_PERIOD && tokenizer->get_token(1) == GDScriptTokenizer::TK_PERIOD) {
2110 // match everything
2111 tokenizer->advance(2);
2112 PatternNode *sub_pattern = alloc_node<PatternNode>();
2113 sub_pattern->pt_type = GDScriptParser::PatternNode::PT_IGNORE_REST;
2114 pattern->array.push_back(sub_pattern);
2115 if (tokenizer->get_token() == GDScriptTokenizer::TK_COMMA && tokenizer->get_token(1) == GDScriptTokenizer::TK_BRACKET_CLOSE) {
2116 tokenizer->advance(2);
2117 break;
2118 } else if (tokenizer->get_token() == GDScriptTokenizer::TK_BRACKET_CLOSE) {
2119 tokenizer->advance(1);
2120 break;
2121 } else {
2122 _set_error("'..' pattern only allowed at the end of an array pattern");
2123 return NULL;
2124 }
2125 }
2126
2127 PatternNode *sub_pattern = _parse_pattern(p_static);
2128 if (!sub_pattern) {
2129 return NULL;
2130 }
2131
2132 pattern->array.push_back(sub_pattern);
2133
2134 if (tokenizer->get_token() == GDScriptTokenizer::TK_COMMA) {
2135 tokenizer->advance();
2136 continue;
2137 } else if (tokenizer->get_token() == GDScriptTokenizer::TK_BRACKET_CLOSE) {
2138 tokenizer->advance();
2139 break;
2140 } else {
2141 _set_error("Not a valid pattern");
2142 return NULL;
2143 }
2144 }
2145 } break;
2146 // bind
2147 case GDScriptTokenizer::TK_PR_VAR: {
2148 tokenizer->advance();
2149 if (!tokenizer->is_token_literal()) {
2150 _set_error("Expected identifier for binding variable name.");
2151 return NULL;
2152 }
2153 pattern->pt_type = GDScriptParser::PatternNode::PT_BIND;
2154 pattern->bind = tokenizer->get_token_literal();
2155 // Check if variable name is already used
2156 BlockNode *bl = current_block;
2157 while (bl) {
2158 if (bl->variables.has(pattern->bind)) {
2159 _set_error("Binding name of '" + pattern->bind.operator String() + "' is already declared in this scope.");
2160 return NULL;
2161 }
2162 bl = bl->parent_block;
2163 }
2164 // Create local variable for proper identifier detection later
2165 LocalVarNode *lv = alloc_node<LocalVarNode>();
2166 lv->name = pattern->bind;
2167 current_block->variables.insert(lv->name, lv);
2168 tokenizer->advance();
2169 } break;
2170 // dictionary
2171 case GDScriptTokenizer::TK_CURLY_BRACKET_OPEN: {
2172 tokenizer->advance();
2173 pattern->pt_type = GDScriptParser::PatternNode::PT_DICTIONARY;
2174 while (true) {
2175
2176 if (tokenizer->get_token() == GDScriptTokenizer::TK_CURLY_BRACKET_CLOSE) {
2177 tokenizer->advance();
2178 break;
2179 }
2180
2181 if (tokenizer->get_token() == GDScriptTokenizer::TK_PERIOD && tokenizer->get_token(1) == GDScriptTokenizer::TK_PERIOD) {
2182 // match everything
2183 tokenizer->advance(2);
2184 PatternNode *sub_pattern = alloc_node<PatternNode>();
2185 sub_pattern->pt_type = PatternNode::PT_IGNORE_REST;
2186 pattern->array.push_back(sub_pattern);
2187 if (tokenizer->get_token() == GDScriptTokenizer::TK_COMMA && tokenizer->get_token(1) == GDScriptTokenizer::TK_CURLY_BRACKET_CLOSE) {
2188 tokenizer->advance(2);
2189 break;
2190 } else if (tokenizer->get_token() == GDScriptTokenizer::TK_CURLY_BRACKET_CLOSE) {
2191 tokenizer->advance(1);
2192 break;
2193 } else {
2194 _set_error("'..' pattern only allowed at the end of a dictionary pattern");
2195 return NULL;
2196 }
2197 }
2198
2199 Node *key = _parse_and_reduce_expression(pattern, p_static);
2200 if (!key) {
2201 _set_error("Not a valid key in pattern");
2202 return NULL;
2203 }
2204
2205 if (key->type != GDScriptParser::Node::TYPE_CONSTANT) {
2206 _set_error("Not a constant expression as key");
2207 return NULL;
2208 }
2209
2210 if (tokenizer->get_token() == GDScriptTokenizer::TK_COLON) {
2211 tokenizer->advance();
2212
2213 PatternNode *value = _parse_pattern(p_static);
2214 if (!value) {
2215 _set_error("Expected pattern in dictionary value");
2216 return NULL;
2217 }
2218
2219 pattern->dictionary.insert(static_cast<ConstantNode *>(key), value);
2220 } else {
2221 pattern->dictionary.insert(static_cast<ConstantNode *>(key), NULL);
2222 }
2223
2224 if (tokenizer->get_token() == GDScriptTokenizer::TK_COMMA) {
2225 tokenizer->advance();
2226 continue;
2227 } else if (tokenizer->get_token() == GDScriptTokenizer::TK_CURLY_BRACKET_CLOSE) {
2228 tokenizer->advance();
2229 break;
2230 } else {
2231 _set_error("Not a valid pattern");
2232 return NULL;
2233 }
2234 }
2235 } break;
2236 case GDScriptTokenizer::TK_WILDCARD: {
2237 tokenizer->advance();
2238 pattern->pt_type = PatternNode::PT_WILDCARD;
2239 } break;
2240 // all the constants like strings and numbers
2241 default: {
2242 Node *value = _parse_and_reduce_expression(pattern, p_static);
2243 if (!value) {
2244 _set_error("Expect constant expression or variables in a pattern");
2245 return NULL;
2246 }
2247
2248 if (value->type == Node::TYPE_OPERATOR) {
2249 // Maybe it's SomeEnum.VALUE
2250 Node *current_value = value;
2251
2252 while (current_value->type == Node::TYPE_OPERATOR) {
2253 OperatorNode *op_node = static_cast<OperatorNode *>(current_value);
2254
2255 if (op_node->op != OperatorNode::OP_INDEX_NAMED) {
2256 _set_error("Invalid operator in pattern. Only index (`A.B`) is allowed");
2257 return NULL;
2258 }
2259 current_value = op_node->arguments[0];
2260 }
2261
2262 if (current_value->type != Node::TYPE_IDENTIFIER) {
2263 _set_error("Only constant expression or variables allowed in a pattern");
2264 return NULL;
2265 }
2266
2267 } else if (value->type != Node::TYPE_IDENTIFIER && value->type != Node::TYPE_CONSTANT) {
2268 _set_error("Only constant expressions or variables allowed in a pattern");
2269 return NULL;
2270 }
2271
2272 pattern->pt_type = PatternNode::PT_CONSTANT;
2273 pattern->constant = value;
2274 } break;
2275 }
2276
2277 return pattern;
2278 }
2279
_parse_pattern_block(BlockNode * p_block,Vector<PatternBranchNode * > & p_branches,bool p_static)2280 void GDScriptParser::_parse_pattern_block(BlockNode *p_block, Vector<PatternBranchNode *> &p_branches, bool p_static) {
2281 IndentLevel current_level = indent_level.back()->get();
2282
2283 p_block->has_return = true;
2284
2285 bool catch_all_appeared = false;
2286
2287 while (true) {
2288
2289 while (tokenizer->get_token() == GDScriptTokenizer::TK_NEWLINE && _parse_newline())
2290 ;
2291
2292 // GDScriptTokenizer::Token token = tokenizer->get_token();
2293 if (error_set)
2294 return;
2295
2296 if (current_level.indent > indent_level.back()->get().indent) {
2297 break; // go back a level
2298 }
2299
2300 pending_newline = -1;
2301
2302 PatternBranchNode *branch = alloc_node<PatternBranchNode>();
2303 branch->body = alloc_node<BlockNode>();
2304 branch->body->parent_block = p_block;
2305 p_block->sub_blocks.push_back(branch->body);
2306 current_block = branch->body;
2307
2308 branch->patterns.push_back(_parse_pattern(p_static));
2309 if (!branch->patterns[0]) {
2310 break;
2311 }
2312
2313 bool has_binding = branch->patterns[0]->pt_type == PatternNode::PT_BIND;
2314 bool catch_all = has_binding || branch->patterns[0]->pt_type == PatternNode::PT_WILDCARD;
2315
2316 #ifdef DEBUG_ENABLED
2317 // Branches after a wildcard or binding are unreachable
2318 if (catch_all_appeared && !current_function->has_unreachable_code) {
2319 _add_warning(GDScriptWarning::UNREACHABLE_CODE, -1, current_function->name.operator String());
2320 current_function->has_unreachable_code = true;
2321 }
2322 #endif
2323
2324 while (tokenizer->get_token() == GDScriptTokenizer::TK_COMMA) {
2325 tokenizer->advance();
2326 branch->patterns.push_back(_parse_pattern(p_static));
2327 if (!branch->patterns[branch->patterns.size() - 1]) {
2328 return;
2329 }
2330
2331 PatternNode::PatternType pt = branch->patterns[branch->patterns.size() - 1]->pt_type;
2332
2333 if (pt == PatternNode::PT_BIND) {
2334 _set_error("Cannot use bindings with multipattern.");
2335 return;
2336 }
2337
2338 catch_all = catch_all || pt == PatternNode::PT_WILDCARD;
2339 }
2340
2341 catch_all_appeared = catch_all_appeared || catch_all;
2342
2343 if (!_enter_indent_block()) {
2344 _set_error("Expected block in pattern branch");
2345 return;
2346 }
2347
2348 _parse_block(branch->body, p_static);
2349
2350 current_block = p_block;
2351
2352 if (!branch->body->has_return) {
2353 p_block->has_return = false;
2354 }
2355
2356 p_branches.push_back(branch);
2357 }
2358
2359 // Even if all branches return, there is possibility of default fallthrough
2360 if (!catch_all_appeared) {
2361 p_block->has_return = false;
2362 }
2363 }
2364
_generate_pattern(PatternNode * p_pattern,Node * p_node_to_match,Node * & p_resulting_node,Map<StringName,Node * > & p_bindings)2365 void GDScriptParser::_generate_pattern(PatternNode *p_pattern, Node *p_node_to_match, Node *&p_resulting_node, Map<StringName, Node *> &p_bindings) {
2366
2367 const DataType &to_match_type = p_node_to_match->get_datatype();
2368
2369 switch (p_pattern->pt_type) {
2370 case PatternNode::PT_CONSTANT: {
2371
2372 DataType pattern_type = _reduce_node_type(p_pattern->constant);
2373 if (error_set) {
2374 return;
2375 }
2376
2377 OperatorNode *type_comp = NULL;
2378
2379 // static type check if possible
2380 if (pattern_type.has_type && to_match_type.has_type) {
2381 if (!_is_type_compatible(to_match_type, pattern_type) && !_is_type_compatible(pattern_type, to_match_type)) {
2382 _set_error("The pattern type (" + pattern_type.to_string() + ") isn't compatible with the type of the value to match (" + to_match_type.to_string() + ").",
2383 p_pattern->line);
2384 return;
2385 }
2386 } else {
2387 // runtime typecheck
2388 BuiltInFunctionNode *typeof_node = alloc_node<BuiltInFunctionNode>();
2389 typeof_node->function = GDScriptFunctions::TYPE_OF;
2390
2391 OperatorNode *typeof_match_value = alloc_node<OperatorNode>();
2392 typeof_match_value->op = OperatorNode::OP_CALL;
2393 typeof_match_value->arguments.push_back(typeof_node);
2394 typeof_match_value->arguments.push_back(p_node_to_match);
2395
2396 OperatorNode *typeof_pattern_value = alloc_node<OperatorNode>();
2397 typeof_pattern_value->op = OperatorNode::OP_CALL;
2398 typeof_pattern_value->arguments.push_back(typeof_node);
2399 typeof_pattern_value->arguments.push_back(p_pattern->constant);
2400
2401 type_comp = alloc_node<OperatorNode>();
2402 type_comp->op = OperatorNode::OP_EQUAL;
2403 type_comp->arguments.push_back(typeof_match_value);
2404 type_comp->arguments.push_back(typeof_pattern_value);
2405 }
2406
2407 // compare the actual values
2408 OperatorNode *value_comp = alloc_node<OperatorNode>();
2409 value_comp->op = OperatorNode::OP_EQUAL;
2410 value_comp->arguments.push_back(p_pattern->constant);
2411 value_comp->arguments.push_back(p_node_to_match);
2412
2413 if (type_comp) {
2414 OperatorNode *full_comparison = alloc_node<OperatorNode>();
2415 full_comparison->op = OperatorNode::OP_AND;
2416 full_comparison->arguments.push_back(type_comp);
2417 full_comparison->arguments.push_back(value_comp);
2418
2419 p_resulting_node = full_comparison;
2420 } else {
2421 p_resulting_node = value_comp;
2422 }
2423
2424 } break;
2425 case PatternNode::PT_BIND: {
2426 p_bindings[p_pattern->bind] = p_node_to_match;
2427
2428 // a bind always matches
2429 ConstantNode *true_value = alloc_node<ConstantNode>();
2430 true_value->value = Variant(true);
2431 p_resulting_node = true_value;
2432 } break;
2433 case PatternNode::PT_ARRAY: {
2434
2435 bool open_ended = false;
2436
2437 if (p_pattern->array.size() > 0) {
2438 if (p_pattern->array[p_pattern->array.size() - 1]->pt_type == PatternNode::PT_IGNORE_REST) {
2439 open_ended = true;
2440 }
2441 }
2442
2443 // typeof(value_to_match) == TYPE_ARRAY && value_to_match.size() >= length
2444 // typeof(value_to_match) == TYPE_ARRAY && value_to_match.size() == length
2445
2446 {
2447 OperatorNode *type_comp = NULL;
2448 // static type check if possible
2449 if (to_match_type.has_type) {
2450 // must be an array
2451 if (to_match_type.kind != DataType::BUILTIN || to_match_type.builtin_type != Variant::ARRAY) {
2452 _set_error("Cannot match an array pattern with a non-array expression.", p_pattern->line);
2453 return;
2454 }
2455 } else {
2456 // runtime typecheck
2457 BuiltInFunctionNode *typeof_node = alloc_node<BuiltInFunctionNode>();
2458 typeof_node->function = GDScriptFunctions::TYPE_OF;
2459
2460 OperatorNode *typeof_match_value = alloc_node<OperatorNode>();
2461 typeof_match_value->op = OperatorNode::OP_CALL;
2462 typeof_match_value->arguments.push_back(typeof_node);
2463 typeof_match_value->arguments.push_back(p_node_to_match);
2464
2465 IdentifierNode *typeof_array = alloc_node<IdentifierNode>();
2466 typeof_array->name = "TYPE_ARRAY";
2467
2468 type_comp = alloc_node<OperatorNode>();
2469 type_comp->op = OperatorNode::OP_EQUAL;
2470 type_comp->arguments.push_back(typeof_match_value);
2471 type_comp->arguments.push_back(typeof_array);
2472 }
2473
2474 // size
2475 ConstantNode *length = alloc_node<ConstantNode>();
2476 length->value = Variant(open_ended ? p_pattern->array.size() - 1 : p_pattern->array.size());
2477
2478 OperatorNode *call = alloc_node<OperatorNode>();
2479 call->op = OperatorNode::OP_CALL;
2480 call->arguments.push_back(p_node_to_match);
2481
2482 IdentifierNode *size = alloc_node<IdentifierNode>();
2483 size->name = "size";
2484 call->arguments.push_back(size);
2485
2486 OperatorNode *length_comparison = alloc_node<OperatorNode>();
2487 length_comparison->op = open_ended ? OperatorNode::OP_GREATER_EQUAL : OperatorNode::OP_EQUAL;
2488 length_comparison->arguments.push_back(call);
2489 length_comparison->arguments.push_back(length);
2490
2491 if (type_comp) {
2492 OperatorNode *type_and_length_comparison = alloc_node<OperatorNode>();
2493 type_and_length_comparison->op = OperatorNode::OP_AND;
2494 type_and_length_comparison->arguments.push_back(type_comp);
2495 type_and_length_comparison->arguments.push_back(length_comparison);
2496
2497 p_resulting_node = type_and_length_comparison;
2498 } else {
2499 p_resulting_node = length_comparison;
2500 }
2501 }
2502
2503 for (int i = 0; i < p_pattern->array.size(); i++) {
2504 PatternNode *pattern = p_pattern->array[i];
2505
2506 Node *condition = NULL;
2507
2508 ConstantNode *index = alloc_node<ConstantNode>();
2509 index->value = Variant(i);
2510
2511 OperatorNode *indexed_value = alloc_node<OperatorNode>();
2512 indexed_value->op = OperatorNode::OP_INDEX;
2513 indexed_value->arguments.push_back(p_node_to_match);
2514 indexed_value->arguments.push_back(index);
2515
2516 _generate_pattern(pattern, indexed_value, condition, p_bindings);
2517
2518 // concatenate all the patterns with &&
2519 OperatorNode *and_node = alloc_node<OperatorNode>();
2520 and_node->op = OperatorNode::OP_AND;
2521 and_node->arguments.push_back(p_resulting_node);
2522 and_node->arguments.push_back(condition);
2523
2524 p_resulting_node = and_node;
2525 }
2526
2527 } break;
2528 case PatternNode::PT_DICTIONARY: {
2529
2530 bool open_ended = false;
2531
2532 if (p_pattern->array.size() > 0) {
2533 open_ended = true;
2534 }
2535
2536 // typeof(value_to_match) == TYPE_DICTIONARY && value_to_match.size() >= length
2537 // typeof(value_to_match) == TYPE_DICTIONARY && value_to_match.size() == length
2538
2539 {
2540 OperatorNode *type_comp = NULL;
2541 // static type check if possible
2542 if (to_match_type.has_type) {
2543 // must be an dictionary
2544 if (to_match_type.kind != DataType::BUILTIN || to_match_type.builtin_type != Variant::DICTIONARY) {
2545 _set_error("Cannot match an dictionary pattern with a non-dictionary expression.", p_pattern->line);
2546 return;
2547 }
2548 } else {
2549 // runtime typecheck
2550 BuiltInFunctionNode *typeof_node = alloc_node<BuiltInFunctionNode>();
2551 typeof_node->function = GDScriptFunctions::TYPE_OF;
2552
2553 OperatorNode *typeof_match_value = alloc_node<OperatorNode>();
2554 typeof_match_value->op = OperatorNode::OP_CALL;
2555 typeof_match_value->arguments.push_back(typeof_node);
2556 typeof_match_value->arguments.push_back(p_node_to_match);
2557
2558 IdentifierNode *typeof_dictionary = alloc_node<IdentifierNode>();
2559 typeof_dictionary->name = "TYPE_DICTIONARY";
2560
2561 type_comp = alloc_node<OperatorNode>();
2562 type_comp->op = OperatorNode::OP_EQUAL;
2563 type_comp->arguments.push_back(typeof_match_value);
2564 type_comp->arguments.push_back(typeof_dictionary);
2565 }
2566
2567 // size
2568 ConstantNode *length = alloc_node<ConstantNode>();
2569 length->value = Variant(open_ended ? p_pattern->dictionary.size() - 1 : p_pattern->dictionary.size());
2570
2571 OperatorNode *call = alloc_node<OperatorNode>();
2572 call->op = OperatorNode::OP_CALL;
2573 call->arguments.push_back(p_node_to_match);
2574
2575 IdentifierNode *size = alloc_node<IdentifierNode>();
2576 size->name = "size";
2577 call->arguments.push_back(size);
2578
2579 OperatorNode *length_comparison = alloc_node<OperatorNode>();
2580 length_comparison->op = open_ended ? OperatorNode::OP_GREATER_EQUAL : OperatorNode::OP_EQUAL;
2581 length_comparison->arguments.push_back(call);
2582 length_comparison->arguments.push_back(length);
2583
2584 if (type_comp) {
2585 OperatorNode *type_and_length_comparison = alloc_node<OperatorNode>();
2586 type_and_length_comparison->op = OperatorNode::OP_AND;
2587 type_and_length_comparison->arguments.push_back(type_comp);
2588 type_and_length_comparison->arguments.push_back(length_comparison);
2589
2590 p_resulting_node = type_and_length_comparison;
2591 } else {
2592 p_resulting_node = length_comparison;
2593 }
2594 }
2595
2596 for (Map<ConstantNode *, PatternNode *>::Element *e = p_pattern->dictionary.front(); e; e = e->next()) {
2597
2598 Node *condition = NULL;
2599
2600 // check for has, then for pattern
2601
2602 IdentifierNode *has = alloc_node<IdentifierNode>();
2603 has->name = "has";
2604
2605 OperatorNode *has_call = alloc_node<OperatorNode>();
2606 has_call->op = OperatorNode::OP_CALL;
2607 has_call->arguments.push_back(p_node_to_match);
2608 has_call->arguments.push_back(has);
2609 has_call->arguments.push_back(e->key());
2610
2611 if (e->value()) {
2612
2613 OperatorNode *indexed_value = alloc_node<OperatorNode>();
2614 indexed_value->op = OperatorNode::OP_INDEX;
2615 indexed_value->arguments.push_back(p_node_to_match);
2616 indexed_value->arguments.push_back(e->key());
2617
2618 _generate_pattern(e->value(), indexed_value, condition, p_bindings);
2619
2620 OperatorNode *has_and_pattern = alloc_node<OperatorNode>();
2621 has_and_pattern->op = OperatorNode::OP_AND;
2622 has_and_pattern->arguments.push_back(has_call);
2623 has_and_pattern->arguments.push_back(condition);
2624
2625 condition = has_and_pattern;
2626
2627 } else {
2628 condition = has_call;
2629 }
2630
2631 // concatenate all the patterns with &&
2632 OperatorNode *and_node = alloc_node<OperatorNode>();
2633 and_node->op = OperatorNode::OP_AND;
2634 and_node->arguments.push_back(p_resulting_node);
2635 and_node->arguments.push_back(condition);
2636
2637 p_resulting_node = and_node;
2638 }
2639
2640 } break;
2641 case PatternNode::PT_IGNORE_REST:
2642 case PatternNode::PT_WILDCARD: {
2643 // simply generate a `true`
2644 ConstantNode *true_value = alloc_node<ConstantNode>();
2645 true_value->value = Variant(true);
2646 p_resulting_node = true_value;
2647 } break;
2648 default: {
2649
2650 } break;
2651 }
2652 }
2653
_transform_match_statment(MatchNode * p_match_statement)2654 void GDScriptParser::_transform_match_statment(MatchNode *p_match_statement) {
2655 IdentifierNode *id = alloc_node<IdentifierNode>();
2656 id->name = "#match_value";
2657 id->line = p_match_statement->line;
2658 id->datatype = _reduce_node_type(p_match_statement->val_to_match);
2659 if (id->datatype.has_type) {
2660 _mark_line_as_safe(id->line);
2661 } else {
2662 _mark_line_as_unsafe(id->line);
2663 }
2664
2665 if (error_set) {
2666 return;
2667 }
2668
2669 for (int i = 0; i < p_match_statement->branches.size(); i++) {
2670
2671 PatternBranchNode *branch = p_match_statement->branches[i];
2672
2673 MatchNode::CompiledPatternBranch compiled_branch;
2674 compiled_branch.compiled_pattern = NULL;
2675
2676 Map<StringName, Node *> binding;
2677
2678 for (int j = 0; j < branch->patterns.size(); j++) {
2679 PatternNode *pattern = branch->patterns[j];
2680 _mark_line_as_safe(pattern->line);
2681
2682 Map<StringName, Node *> bindings;
2683 Node *resulting_node = NULL;
2684 _generate_pattern(pattern, id, resulting_node, bindings);
2685
2686 if (!resulting_node) {
2687 return;
2688 }
2689
2690 if (!binding.empty() && !bindings.empty()) {
2691 _set_error("Multipatterns can't contain bindings");
2692 return;
2693 } else {
2694 binding = bindings;
2695 }
2696
2697 // Result is always a boolean
2698 DataType resulting_node_type;
2699 resulting_node_type.has_type = true;
2700 resulting_node_type.is_constant = true;
2701 resulting_node_type.kind = DataType::BUILTIN;
2702 resulting_node_type.builtin_type = Variant::BOOL;
2703 resulting_node->set_datatype(resulting_node_type);
2704
2705 if (compiled_branch.compiled_pattern) {
2706 OperatorNode *or_node = alloc_node<OperatorNode>();
2707 or_node->op = OperatorNode::OP_OR;
2708 or_node->arguments.push_back(compiled_branch.compiled_pattern);
2709 or_node->arguments.push_back(resulting_node);
2710
2711 compiled_branch.compiled_pattern = or_node;
2712 } else {
2713 // single pattern | first one
2714 compiled_branch.compiled_pattern = resulting_node;
2715 }
2716 }
2717
2718 // prepare the body ...hehe
2719 for (Map<StringName, Node *>::Element *e = binding.front(); e; e = e->next()) {
2720 if (!branch->body->variables.has(e->key())) {
2721 _set_error("Parser bug: missing pattern bind variable.", branch->line);
2722 ERR_FAIL();
2723 }
2724
2725 LocalVarNode *local_var = branch->body->variables[e->key()];
2726 local_var->assign = e->value();
2727 local_var->set_datatype(local_var->assign->get_datatype());
2728 local_var->assignments++;
2729
2730 IdentifierNode *id2 = alloc_node<IdentifierNode>();
2731 id2->name = local_var->name;
2732 id2->datatype = local_var->datatype;
2733 id2->declared_block = branch->body;
2734 id2->set_datatype(local_var->assign->get_datatype());
2735
2736 OperatorNode *op = alloc_node<OperatorNode>();
2737 op->op = OperatorNode::OP_ASSIGN;
2738 op->arguments.push_back(id2);
2739 op->arguments.push_back(local_var->assign);
2740 local_var->assign_op = op;
2741
2742 branch->body->statements.push_front(op);
2743 branch->body->statements.push_front(local_var);
2744 }
2745
2746 compiled_branch.body = branch->body;
2747
2748 p_match_statement->compiled_pattern_branches.push_back(compiled_branch);
2749 }
2750 }
2751
_parse_block(BlockNode * p_block,bool p_static)2752 void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) {
2753
2754 IndentLevel current_level = indent_level.back()->get();
2755
2756 #ifdef DEBUG_ENABLED
2757
2758 pending_newline = -1; // reset for the new block
2759
2760 NewLineNode *nl = alloc_node<NewLineNode>();
2761
2762 nl->line = tokenizer->get_token_line();
2763 p_block->statements.push_back(nl);
2764 #endif
2765
2766 bool is_first_line = true;
2767
2768 while (true) {
2769 if (!is_first_line && indent_level.back()->prev() && indent_level.back()->prev()->get().indent == current_level.indent) {
2770 if (indent_level.back()->prev()->get().is_mixed(current_level)) {
2771 _set_error("Mixed tabs and spaces in indentation.");
2772 return;
2773 }
2774 // pythonic single-line expression, don't parse future lines
2775 indent_level.pop_back();
2776 p_block->end_line = tokenizer->get_token_line();
2777 return;
2778 }
2779 is_first_line = false;
2780
2781 GDScriptTokenizer::Token token = tokenizer->get_token();
2782 if (error_set)
2783 return;
2784
2785 if (current_level.indent > indent_level.back()->get().indent) {
2786 p_block->end_line = tokenizer->get_token_line();
2787 return; //go back a level
2788 }
2789
2790 if (pending_newline != -1) {
2791
2792 NewLineNode *nl2 = alloc_node<NewLineNode>();
2793 nl2->line = pending_newline;
2794 p_block->statements.push_back(nl2);
2795 pending_newline = -1;
2796 }
2797
2798 #ifdef DEBUG_ENABLED
2799 switch (token) {
2800 case GDScriptTokenizer::TK_EOF:
2801 case GDScriptTokenizer::TK_ERROR:
2802 case GDScriptTokenizer::TK_NEWLINE:
2803 case GDScriptTokenizer::TK_CF_PASS: {
2804 // will check later
2805 } break;
2806 default: {
2807 if (p_block->has_return && !current_function->has_unreachable_code) {
2808 _add_warning(GDScriptWarning::UNREACHABLE_CODE, -1, current_function->name.operator String());
2809 current_function->has_unreachable_code = true;
2810 }
2811 } break;
2812 }
2813 #endif // DEBUG_ENABLED
2814 switch (token) {
2815 case GDScriptTokenizer::TK_EOF:
2816 p_block->end_line = tokenizer->get_token_line();
2817 case GDScriptTokenizer::TK_ERROR: {
2818 return; //go back
2819
2820 //end of file!
2821
2822 } break;
2823 case GDScriptTokenizer::TK_NEWLINE: {
2824
2825 int line = tokenizer->get_token_line();
2826
2827 if (!_parse_newline()) {
2828 if (!error_set) {
2829 p_block->end_line = tokenizer->get_token_line();
2830 pending_newline = p_block->end_line;
2831 }
2832 return;
2833 }
2834
2835 _mark_line_as_safe(line);
2836 NewLineNode *nl2 = alloc_node<NewLineNode>();
2837 nl2->line = line;
2838 p_block->statements.push_back(nl2);
2839
2840 } break;
2841 case GDScriptTokenizer::TK_CF_PASS: {
2842 if (tokenizer->get_token(1) != GDScriptTokenizer::TK_SEMICOLON && tokenizer->get_token(1) != GDScriptTokenizer::TK_NEWLINE && tokenizer->get_token(1) != GDScriptTokenizer::TK_EOF) {
2843
2844 _set_error("Expected \";\" or a line break.");
2845 return;
2846 }
2847 _mark_line_as_safe(tokenizer->get_token_line());
2848 tokenizer->advance();
2849 if (tokenizer->get_token() == GDScriptTokenizer::TK_SEMICOLON) {
2850 // Ignore semicolon after 'pass'.
2851 tokenizer->advance();
2852 }
2853 } break;
2854 case GDScriptTokenizer::TK_PR_VAR: {
2855 // Variable declaration and (eventual) initialization.
2856
2857 tokenizer->advance();
2858 int var_line = tokenizer->get_token_line();
2859 if (!tokenizer->is_token_literal(0, true)) {
2860
2861 _set_error("Expected an identifier for the local variable name.");
2862 return;
2863 }
2864 StringName n = tokenizer->get_token_literal();
2865 tokenizer->advance();
2866 if (current_function) {
2867 for (int i = 0; i < current_function->arguments.size(); i++) {
2868 if (n == current_function->arguments[i]) {
2869 _set_error("Variable \"" + String(n) + "\" already defined in the scope (at line " + itos(current_function->line) + ").");
2870 return;
2871 }
2872 }
2873 }
2874 BlockNode *check_block = p_block;
2875 while (check_block) {
2876 if (check_block->variables.has(n)) {
2877 _set_error("Variable \"" + String(n) + "\" already defined in the scope (at line " + itos(check_block->variables[n]->line) + ").");
2878 return;
2879 }
2880 check_block = check_block->parent_block;
2881 }
2882
2883 //must know when the local variable is declared
2884 LocalVarNode *lv = alloc_node<LocalVarNode>();
2885 lv->name = n;
2886 lv->line = var_line;
2887 p_block->statements.push_back(lv);
2888
2889 Node *assigned = NULL;
2890
2891 if (tokenizer->get_token() == GDScriptTokenizer::TK_COLON) {
2892 if (tokenizer->get_token(1) == GDScriptTokenizer::TK_OP_ASSIGN) {
2893 lv->datatype = DataType();
2894 #ifdef DEBUG_ENABLED
2895 lv->datatype.infer_type = true;
2896 #endif
2897 tokenizer->advance();
2898 } else if (!_parse_type(lv->datatype)) {
2899 _set_error("Expected a type for the variable.");
2900 return;
2901 }
2902 }
2903
2904 if (tokenizer->get_token() == GDScriptTokenizer::TK_OP_ASSIGN) {
2905
2906 tokenizer->advance();
2907 Node *subexpr = _parse_and_reduce_expression(p_block, p_static);
2908 if (!subexpr) {
2909 if (_recover_from_completion()) {
2910 break;
2911 }
2912 return;
2913 }
2914
2915 lv->assignments++;
2916 assigned = subexpr;
2917 } else {
2918
2919 assigned = _get_default_value_for_type(lv->datatype, var_line);
2920 }
2921 //must be added later, to avoid self-referencing.
2922 p_block->variables.insert(n, lv);
2923
2924 IdentifierNode *id = alloc_node<IdentifierNode>();
2925 id->name = n;
2926 id->declared_block = p_block;
2927 id->line = var_line;
2928
2929 OperatorNode *op = alloc_node<OperatorNode>();
2930 op->op = OperatorNode::OP_ASSIGN;
2931 op->arguments.push_back(id);
2932 op->arguments.push_back(assigned);
2933 op->line = var_line;
2934 p_block->statements.push_back(op);
2935 lv->assign_op = op;
2936 lv->assign = assigned;
2937
2938 if (!_end_statement()) {
2939 _set_end_statement_error("var");
2940 return;
2941 }
2942
2943 } break;
2944 case GDScriptTokenizer::TK_CF_IF: {
2945
2946 tokenizer->advance();
2947
2948 Node *condition = _parse_and_reduce_expression(p_block, p_static);
2949 if (!condition) {
2950 if (_recover_from_completion()) {
2951 break;
2952 }
2953 return;
2954 }
2955
2956 ControlFlowNode *cf_if = alloc_node<ControlFlowNode>();
2957
2958 cf_if->cf_type = ControlFlowNode::CF_IF;
2959 cf_if->arguments.push_back(condition);
2960
2961 cf_if->body = alloc_node<BlockNode>();
2962 cf_if->body->parent_block = p_block;
2963 cf_if->body->if_condition = condition; //helps code completion
2964
2965 p_block->sub_blocks.push_back(cf_if->body);
2966
2967 if (!_enter_indent_block(cf_if->body)) {
2968 _set_error("Expected an indented block after \"if\".");
2969 p_block->end_line = tokenizer->get_token_line();
2970 return;
2971 }
2972
2973 current_block = cf_if->body;
2974 _parse_block(cf_if->body, p_static);
2975 current_block = p_block;
2976
2977 if (error_set)
2978 return;
2979 p_block->statements.push_back(cf_if);
2980
2981 bool all_have_return = cf_if->body->has_return;
2982 bool have_else = false;
2983
2984 while (true) {
2985
2986 while (tokenizer->get_token() == GDScriptTokenizer::TK_NEWLINE && _parse_newline())
2987 ;
2988
2989 if (indent_level.back()->get().indent < current_level.indent) { //not at current indent level
2990 p_block->end_line = tokenizer->get_token_line();
2991 return;
2992 }
2993
2994 if (tokenizer->get_token() == GDScriptTokenizer::TK_CF_ELIF) {
2995
2996 if (indent_level.back()->get().indent > current_level.indent) {
2997
2998 _set_error("Invalid indentation.");
2999 return;
3000 }
3001
3002 tokenizer->advance();
3003
3004 cf_if->body_else = alloc_node<BlockNode>();
3005 cf_if->body_else->parent_block = p_block;
3006 p_block->sub_blocks.push_back(cf_if->body_else);
3007
3008 ControlFlowNode *cf_else = alloc_node<ControlFlowNode>();
3009 cf_else->cf_type = ControlFlowNode::CF_IF;
3010
3011 //condition
3012 Node *condition2 = _parse_and_reduce_expression(p_block, p_static);
3013 if (!condition2) {
3014 if (_recover_from_completion()) {
3015 break;
3016 }
3017 return;
3018 }
3019 cf_else->arguments.push_back(condition2);
3020 cf_else->cf_type = ControlFlowNode::CF_IF;
3021
3022 cf_if->body_else->statements.push_back(cf_else);
3023 cf_if = cf_else;
3024 cf_if->body = alloc_node<BlockNode>();
3025 cf_if->body->parent_block = p_block;
3026 p_block->sub_blocks.push_back(cf_if->body);
3027
3028 if (!_enter_indent_block(cf_if->body)) {
3029 _set_error("Expected an indented block after \"elif\".");
3030 p_block->end_line = tokenizer->get_token_line();
3031 return;
3032 }
3033
3034 current_block = cf_else->body;
3035 _parse_block(cf_else->body, p_static);
3036 current_block = p_block;
3037 if (error_set)
3038 return;
3039
3040 all_have_return = all_have_return && cf_else->body->has_return;
3041
3042 } else if (tokenizer->get_token() == GDScriptTokenizer::TK_CF_ELSE) {
3043
3044 if (indent_level.back()->get().indent > current_level.indent) {
3045 _set_error("Invalid indentation.");
3046 return;
3047 }
3048
3049 tokenizer->advance();
3050 cf_if->body_else = alloc_node<BlockNode>();
3051 cf_if->body_else->parent_block = p_block;
3052 p_block->sub_blocks.push_back(cf_if->body_else);
3053
3054 if (!_enter_indent_block(cf_if->body_else)) {
3055 _set_error("Expected an indented block after \"else\".");
3056 p_block->end_line = tokenizer->get_token_line();
3057 return;
3058 }
3059 current_block = cf_if->body_else;
3060 _parse_block(cf_if->body_else, p_static);
3061 current_block = p_block;
3062 if (error_set)
3063 return;
3064
3065 all_have_return = all_have_return && cf_if->body_else->has_return;
3066 have_else = true;
3067
3068 break; //after else, exit
3069
3070 } else
3071 break;
3072 }
3073
3074 cf_if->body->has_return = all_have_return;
3075 // If there's no else block, path out of the if might not have a return
3076 p_block->has_return = all_have_return && have_else;
3077
3078 } break;
3079 case GDScriptTokenizer::TK_CF_WHILE: {
3080
3081 tokenizer->advance();
3082 Node *condition2 = _parse_and_reduce_expression(p_block, p_static);
3083 if (!condition2) {
3084 if (_recover_from_completion()) {
3085 break;
3086 }
3087 return;
3088 }
3089
3090 ControlFlowNode *cf_while = alloc_node<ControlFlowNode>();
3091
3092 cf_while->cf_type = ControlFlowNode::CF_WHILE;
3093 cf_while->arguments.push_back(condition2);
3094
3095 cf_while->body = alloc_node<BlockNode>();
3096 cf_while->body->parent_block = p_block;
3097 cf_while->body->can_break = true;
3098 cf_while->body->can_continue = true;
3099 p_block->sub_blocks.push_back(cf_while->body);
3100
3101 if (!_enter_indent_block(cf_while->body)) {
3102 _set_error("Expected an indented block after \"while\".");
3103 p_block->end_line = tokenizer->get_token_line();
3104 return;
3105 }
3106
3107 current_block = cf_while->body;
3108 _parse_block(cf_while->body, p_static);
3109 current_block = p_block;
3110 if (error_set)
3111 return;
3112 p_block->statements.push_back(cf_while);
3113 } break;
3114 case GDScriptTokenizer::TK_CF_FOR: {
3115
3116 tokenizer->advance();
3117
3118 if (!tokenizer->is_token_literal(0, true)) {
3119
3120 _set_error("Identifier expected after \"for\".");
3121 }
3122
3123 IdentifierNode *id = alloc_node<IdentifierNode>();
3124 id->name = tokenizer->get_token_identifier();
3125 #ifdef DEBUG_ENABLED
3126 for (int j = 0; j < current_class->variables.size(); j++) {
3127 if (current_class->variables[j].identifier == id->name) {
3128 _add_warning(GDScriptWarning::SHADOWED_VARIABLE, id->line, id->name, itos(current_class->variables[j].line));
3129 }
3130 }
3131 #endif // DEBUG_ENABLED
3132
3133 BlockNode *check_block = p_block;
3134 while (check_block) {
3135 if (check_block->variables.has(id->name)) {
3136 _set_error("Variable \"" + String(id->name) + "\" already defined in the scope (at line " + itos(check_block->variables[id->name]->line) + ").");
3137 return;
3138 }
3139 check_block = check_block->parent_block;
3140 }
3141
3142 tokenizer->advance();
3143
3144 if (tokenizer->get_token() != GDScriptTokenizer::TK_OP_IN) {
3145 _set_error("\"in\" expected after identifier.");
3146 return;
3147 }
3148
3149 tokenizer->advance();
3150
3151 Node *container = _parse_and_reduce_expression(p_block, p_static);
3152 if (!container) {
3153 if (_recover_from_completion()) {
3154 break;
3155 }
3156 return;
3157 }
3158
3159 DataType iter_type;
3160
3161 if (container->type == Node::TYPE_OPERATOR) {
3162
3163 OperatorNode *op = static_cast<OperatorNode *>(container);
3164 if (op->op == OperatorNode::OP_CALL && op->arguments[0]->type == Node::TYPE_BUILT_IN_FUNCTION && static_cast<BuiltInFunctionNode *>(op->arguments[0])->function == GDScriptFunctions::GEN_RANGE) {
3165 //iterating a range, so see if range() can be optimized without allocating memory, by replacing it by vectors (which can work as iterable too!)
3166
3167 Vector<Node *> args;
3168 Vector<double> constants;
3169
3170 bool constant = true;
3171
3172 for (int i = 1; i < op->arguments.size(); i++) {
3173 args.push_back(op->arguments[i]);
3174 if (op->arguments[i]->type == Node::TYPE_CONSTANT) {
3175 ConstantNode *c = static_cast<ConstantNode *>(op->arguments[i]);
3176 if (c->value.get_type() == Variant::REAL || c->value.get_type() == Variant::INT) {
3177 constants.push_back(c->value);
3178 } else {
3179 constant = false;
3180 }
3181 } else {
3182 constant = false;
3183 }
3184 }
3185
3186 if (args.size() > 0 && args.size() < 4) {
3187
3188 if (constant) {
3189
3190 ConstantNode *cn = alloc_node<ConstantNode>();
3191 switch (args.size()) {
3192 case 1: cn->value = (int)constants[0]; break;
3193 case 2: cn->value = Vector2(constants[0], constants[1]); break;
3194 case 3: cn->value = Vector3(constants[0], constants[1], constants[2]); break;
3195 }
3196 cn->datatype = _type_from_variant(cn->value);
3197 container = cn;
3198 } else {
3199 OperatorNode *on = alloc_node<OperatorNode>();
3200 on->op = OperatorNode::OP_CALL;
3201
3202 TypeNode *tn = alloc_node<TypeNode>();
3203 on->arguments.push_back(tn);
3204
3205 switch (args.size()) {
3206 case 1: tn->vtype = Variant::INT; break;
3207 case 2: tn->vtype = Variant::VECTOR2; break;
3208 case 3: tn->vtype = Variant::VECTOR3; break;
3209 }
3210
3211 for (int i = 0; i < args.size(); i++) {
3212 on->arguments.push_back(args[i]);
3213 }
3214
3215 container = on;
3216 }
3217 }
3218
3219 iter_type.has_type = true;
3220 iter_type.kind = DataType::BUILTIN;
3221 iter_type.builtin_type = Variant::INT;
3222 }
3223 }
3224
3225 ControlFlowNode *cf_for = alloc_node<ControlFlowNode>();
3226
3227 cf_for->cf_type = ControlFlowNode::CF_FOR;
3228 cf_for->arguments.push_back(id);
3229 cf_for->arguments.push_back(container);
3230
3231 cf_for->body = alloc_node<BlockNode>();
3232 cf_for->body->parent_block = p_block;
3233 cf_for->body->can_break = true;
3234 cf_for->body->can_continue = true;
3235 p_block->sub_blocks.push_back(cf_for->body);
3236
3237 if (!_enter_indent_block(cf_for->body)) {
3238 _set_error("Expected indented block after \"for\".");
3239 p_block->end_line = tokenizer->get_token_line();
3240 return;
3241 }
3242
3243 current_block = cf_for->body;
3244
3245 // this is for checking variable for redefining
3246 // inside this _parse_block
3247 LocalVarNode *lv = alloc_node<LocalVarNode>();
3248 lv->name = id->name;
3249 lv->line = id->line;
3250 lv->assignments++;
3251 id->declared_block = cf_for->body;
3252 lv->set_datatype(iter_type);
3253 id->set_datatype(iter_type);
3254 cf_for->body->variables.insert(id->name, lv);
3255 _parse_block(cf_for->body, p_static);
3256 current_block = p_block;
3257
3258 if (error_set)
3259 return;
3260 p_block->statements.push_back(cf_for);
3261 } break;
3262 case GDScriptTokenizer::TK_CF_CONTINUE: {
3263 BlockNode *upper_block = p_block;
3264 bool is_continue_valid = false;
3265 while (upper_block) {
3266 if (upper_block->can_continue) {
3267 is_continue_valid = true;
3268 break;
3269 }
3270 upper_block = upper_block->parent_block;
3271 }
3272
3273 if (!is_continue_valid) {
3274 _set_error("Unexpected keyword \"continue\" outside a loop.");
3275 return;
3276 }
3277
3278 _mark_line_as_safe(tokenizer->get_token_line());
3279 tokenizer->advance();
3280 ControlFlowNode *cf_continue = alloc_node<ControlFlowNode>();
3281 cf_continue->cf_type = ControlFlowNode::CF_CONTINUE;
3282 p_block->statements.push_back(cf_continue);
3283 if (!_end_statement()) {
3284 _set_end_statement_error("continue");
3285 return;
3286 }
3287 } break;
3288 case GDScriptTokenizer::TK_CF_BREAK: {
3289 BlockNode *upper_block = p_block;
3290 bool is_break_valid = false;
3291 while (upper_block) {
3292 if (upper_block->can_break) {
3293 is_break_valid = true;
3294 break;
3295 }
3296 upper_block = upper_block->parent_block;
3297 }
3298
3299 if (!is_break_valid) {
3300 _set_error("Unexpected keyword \"break\" outside a loop.");
3301 return;
3302 }
3303
3304 _mark_line_as_safe(tokenizer->get_token_line());
3305 tokenizer->advance();
3306 ControlFlowNode *cf_break = alloc_node<ControlFlowNode>();
3307 cf_break->cf_type = ControlFlowNode::CF_BREAK;
3308 p_block->statements.push_back(cf_break);
3309 if (!_end_statement()) {
3310 _set_end_statement_error("break");
3311 return;
3312 }
3313 } break;
3314 case GDScriptTokenizer::TK_CF_RETURN: {
3315
3316 tokenizer->advance();
3317 ControlFlowNode *cf_return = alloc_node<ControlFlowNode>();
3318 cf_return->cf_type = ControlFlowNode::CF_RETURN;
3319 cf_return->line = tokenizer->get_token_line(-1);
3320
3321 if (tokenizer->get_token() == GDScriptTokenizer::TK_SEMICOLON || tokenizer->get_token() == GDScriptTokenizer::TK_NEWLINE || tokenizer->get_token() == GDScriptTokenizer::TK_EOF) {
3322 //expect end of statement
3323 p_block->statements.push_back(cf_return);
3324 if (!_end_statement()) {
3325 return;
3326 }
3327 } else {
3328 //expect expression
3329 Node *retexpr = _parse_and_reduce_expression(p_block, p_static);
3330 if (!retexpr) {
3331 if (_recover_from_completion()) {
3332 break;
3333 }
3334 return;
3335 }
3336 cf_return->arguments.push_back(retexpr);
3337 p_block->statements.push_back(cf_return);
3338 if (!_end_statement()) {
3339 _set_end_statement_error("return");
3340 return;
3341 }
3342 }
3343 p_block->has_return = true;
3344
3345 } break;
3346 case GDScriptTokenizer::TK_CF_MATCH: {
3347
3348 tokenizer->advance();
3349
3350 MatchNode *match_node = alloc_node<MatchNode>();
3351
3352 Node *val_to_match = _parse_and_reduce_expression(p_block, p_static);
3353
3354 if (!val_to_match) {
3355 if (_recover_from_completion()) {
3356 break;
3357 }
3358 return;
3359 }
3360
3361 match_node->val_to_match = val_to_match;
3362
3363 if (!_enter_indent_block()) {
3364 _set_error("Expected indented pattern matching block after \"match\".");
3365 return;
3366 }
3367
3368 BlockNode *compiled_branches = alloc_node<BlockNode>();
3369 compiled_branches->parent_block = p_block;
3370 compiled_branches->parent_class = p_block->parent_class;
3371 compiled_branches->can_continue = true;
3372
3373 p_block->sub_blocks.push_back(compiled_branches);
3374
3375 _parse_pattern_block(compiled_branches, match_node->branches, p_static);
3376
3377 if (error_set) return;
3378
3379 ControlFlowNode *match_cf_node = alloc_node<ControlFlowNode>();
3380 match_cf_node->cf_type = ControlFlowNode::CF_MATCH;
3381 match_cf_node->match = match_node;
3382 match_cf_node->body = compiled_branches;
3383
3384 p_block->has_return = p_block->has_return || compiled_branches->has_return;
3385 p_block->statements.push_back(match_cf_node);
3386
3387 _end_statement();
3388 } break;
3389 case GDScriptTokenizer::TK_PR_ASSERT: {
3390
3391 tokenizer->advance();
3392
3393 if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_OPEN) {
3394 _set_error("Expected '(' after assert");
3395 return;
3396 }
3397
3398 int assert_line = tokenizer->get_token_line();
3399
3400 tokenizer->advance();
3401
3402 Vector<Node *> args;
3403 const bool result = _parse_arguments(p_block, args, p_static);
3404 if (!result) {
3405 return;
3406 }
3407
3408 if (args.empty() || args.size() > 2) {
3409 _set_error("Wrong number of arguments, expected 1 or 2", assert_line);
3410 return;
3411 }
3412
3413 AssertNode *an = alloc_node<AssertNode>();
3414 an->condition = _reduce_expression(args[0], p_static);
3415 an->line = assert_line;
3416
3417 if (args.size() == 2) {
3418 an->message = _reduce_expression(args[1], p_static);
3419 } else {
3420 ConstantNode *message_node = alloc_node<ConstantNode>();
3421 message_node->value = String();
3422 an->message = message_node;
3423 }
3424
3425 p_block->statements.push_back(an);
3426
3427 if (!_end_statement()) {
3428 _set_end_statement_error("assert");
3429 return;
3430 }
3431 } break;
3432 case GDScriptTokenizer::TK_PR_BREAKPOINT: {
3433
3434 tokenizer->advance();
3435 BreakpointNode *bn = alloc_node<BreakpointNode>();
3436 p_block->statements.push_back(bn);
3437
3438 if (!_end_statement()) {
3439 _set_end_statement_error("breakpoint");
3440 return;
3441 }
3442 } break;
3443 default: {
3444
3445 Node *expression = _parse_and_reduce_expression(p_block, p_static, false, true);
3446 if (!expression) {
3447 if (_recover_from_completion()) {
3448 break;
3449 }
3450 return;
3451 }
3452 p_block->statements.push_back(expression);
3453 if (!_end_statement()) {
3454 // Attempt to guess a better error message if the user "retypes" a variable
3455 if (tokenizer->get_token() == GDScriptTokenizer::TK_COLON && tokenizer->get_token(1) == GDScriptTokenizer::TK_OP_ASSIGN) {
3456 _set_error("Unexpected ':=', use '=' instead. Expected end of statement after expression.");
3457 } else {
3458 _set_error(vformat("Expected end of statement after expression, got %s instead.", tokenizer->get_token_name(tokenizer->get_token())));
3459 }
3460 return;
3461 }
3462
3463 } break;
3464 }
3465 }
3466 }
3467
_parse_newline()3468 bool GDScriptParser::_parse_newline() {
3469
3470 if (tokenizer->get_token(1) != GDScriptTokenizer::TK_EOF && tokenizer->get_token(1) != GDScriptTokenizer::TK_NEWLINE) {
3471
3472 IndentLevel current_level = indent_level.back()->get();
3473 int indent = tokenizer->get_token_line_indent();
3474 int tabs = tokenizer->get_token_line_tab_indent();
3475 IndentLevel new_level(indent, tabs);
3476
3477 if (new_level.is_mixed(current_level)) {
3478 _set_error("Mixed tabs and spaces in indentation.");
3479 return false;
3480 }
3481
3482 if (indent > current_level.indent) {
3483 _set_error("Unexpected indentation.");
3484 return false;
3485 }
3486
3487 if (indent < current_level.indent) {
3488
3489 while (indent < current_level.indent) {
3490
3491 //exit block
3492 if (indent_level.size() == 1) {
3493 _set_error("Invalid indentation. Bug?");
3494 return false;
3495 }
3496
3497 indent_level.pop_back();
3498
3499 if (indent_level.back()->get().indent < indent) {
3500
3501 _set_error("Unindent does not match any outer indentation level.");
3502 return false;
3503 }
3504
3505 if (indent_level.back()->get().is_mixed(current_level)) {
3506 _set_error("Mixed tabs and spaces in indentation.");
3507 return false;
3508 }
3509
3510 current_level = indent_level.back()->get();
3511 }
3512
3513 tokenizer->advance();
3514 return false;
3515 }
3516 }
3517
3518 tokenizer->advance();
3519 return true;
3520 }
3521
_parse_extends(ClassNode * p_class)3522 void GDScriptParser::_parse_extends(ClassNode *p_class) {
3523
3524 if (p_class->extends_used) {
3525
3526 _set_error("\"extends\" can only be present once per script.");
3527 return;
3528 }
3529
3530 if (!p_class->constant_expressions.empty() || !p_class->subclasses.empty() || !p_class->functions.empty() || !p_class->variables.empty()) {
3531
3532 _set_error("\"extends\" must be used before anything else.");
3533 return;
3534 }
3535
3536 p_class->extends_used = true;
3537
3538 tokenizer->advance();
3539
3540 if (tokenizer->get_token() == GDScriptTokenizer::TK_BUILT_IN_TYPE && tokenizer->get_token_type() == Variant::OBJECT) {
3541 p_class->extends_class.push_back(Variant::get_type_name(Variant::OBJECT));
3542 tokenizer->advance();
3543 return;
3544 }
3545
3546 // see if inheritance happens from a file
3547 if (tokenizer->get_token() == GDScriptTokenizer::TK_CONSTANT) {
3548
3549 Variant constant = tokenizer->get_token_constant();
3550 if (constant.get_type() != Variant::STRING) {
3551
3552 _set_error("\"extends\" constant must be a string.");
3553 return;
3554 }
3555
3556 p_class->extends_file = constant;
3557 tokenizer->advance();
3558
3559 // Add parent script as a dependency
3560 String parent = constant;
3561 if (parent.is_rel_path()) {
3562 parent = base_path.plus_file(parent).simplify_path();
3563 }
3564 dependencies.push_back(parent);
3565
3566 if (tokenizer->get_token() != GDScriptTokenizer::TK_PERIOD) {
3567 return;
3568 } else
3569 tokenizer->advance();
3570 }
3571
3572 while (true) {
3573
3574 switch (tokenizer->get_token()) {
3575
3576 case GDScriptTokenizer::TK_IDENTIFIER: {
3577 StringName identifier = tokenizer->get_token_identifier();
3578 p_class->extends_class.push_back(identifier);
3579 } break;
3580
3581 case GDScriptTokenizer::TK_PERIOD:
3582 break;
3583
3584 default: {
3585
3586 _set_error("Invalid \"extends\" syntax, expected string constant (path) and/or identifier (parent class).");
3587 return;
3588 }
3589 }
3590
3591 tokenizer->advance(1);
3592
3593 switch (tokenizer->get_token()) {
3594
3595 case GDScriptTokenizer::TK_IDENTIFIER:
3596 case GDScriptTokenizer::TK_PERIOD:
3597 continue;
3598 case GDScriptTokenizer::TK_CURSOR:
3599 completion_type = COMPLETION_EXTENDS;
3600 completion_class = current_class;
3601 completion_function = current_function;
3602 completion_line = tokenizer->get_token_line();
3603 completion_block = current_block;
3604 completion_ident_is_call = false;
3605 completion_found = true;
3606 return;
3607 default:
3608 return;
3609 }
3610 }
3611 }
3612
_parse_class(ClassNode * p_class)3613 void GDScriptParser::_parse_class(ClassNode *p_class) {
3614
3615 IndentLevel current_level = indent_level.back()->get();
3616
3617 while (true) {
3618
3619 GDScriptTokenizer::Token token = tokenizer->get_token();
3620 if (error_set)
3621 return;
3622
3623 if (current_level.indent > indent_level.back()->get().indent) {
3624 p_class->end_line = tokenizer->get_token_line();
3625 return; //go back a level
3626 }
3627
3628 switch (token) {
3629
3630 case GDScriptTokenizer::TK_CURSOR: {
3631 tokenizer->advance();
3632 } break;
3633 case GDScriptTokenizer::TK_EOF:
3634 p_class->end_line = tokenizer->get_token_line();
3635 case GDScriptTokenizer::TK_ERROR: {
3636 return; //go back
3637 //end of file!
3638 } break;
3639 case GDScriptTokenizer::TK_NEWLINE: {
3640 if (!_parse_newline()) {
3641 if (!error_set) {
3642 p_class->end_line = tokenizer->get_token_line();
3643 }
3644 return;
3645 }
3646 } break;
3647 case GDScriptTokenizer::TK_PR_EXTENDS: {
3648
3649 _mark_line_as_safe(tokenizer->get_token_line());
3650 _parse_extends(p_class);
3651 if (error_set)
3652 return;
3653 if (!_end_statement()) {
3654 _set_end_statement_error("extends");
3655 return;
3656 }
3657
3658 } break;
3659 case GDScriptTokenizer::TK_PR_CLASS_NAME: {
3660
3661 _mark_line_as_safe(tokenizer->get_token_line());
3662 if (p_class->owner) {
3663 _set_error("\"class_name\" is only valid for the main class namespace.");
3664 return;
3665 }
3666 if (self_path.begins_with("res://") && self_path.find("::") != -1) {
3667 _set_error("\"class_name\" isn't allowed in built-in scripts.");
3668 return;
3669 }
3670 if (tokenizer->get_token(1) != GDScriptTokenizer::TK_IDENTIFIER) {
3671
3672 _set_error("\"class_name\" syntax: \"class_name <UniqueName>\"");
3673 return;
3674 }
3675 if (p_class->classname_used) {
3676 _set_error("\"class_name\" can only be present once per script.");
3677 return;
3678 }
3679
3680 p_class->classname_used = true;
3681
3682 p_class->name = tokenizer->get_token_identifier(1);
3683
3684 if (self_path != String() && ScriptServer::is_global_class(p_class->name) && ScriptServer::get_global_class_path(p_class->name) != self_path) {
3685 _set_error("Unique global class \"" + p_class->name + "\" already exists at path: " + ScriptServer::get_global_class_path(p_class->name));
3686 return;
3687 }
3688
3689 if (ClassDB::class_exists(p_class->name)) {
3690 _set_error("The class \"" + p_class->name + "\" shadows a native class.");
3691 return;
3692 }
3693
3694 if (p_class->classname_used && ProjectSettings::get_singleton()->has_setting("autoload/" + p_class->name)) {
3695 const String autoload_path = ProjectSettings::get_singleton()->get_setting("autoload/" + p_class->name);
3696 if (autoload_path.begins_with("*")) {
3697 // It's a singleton, and not just a regular AutoLoad script.
3698 _set_error("The class \"" + p_class->name + "\" conflicts with the AutoLoad singleton of the same name, and is therefore redundant. Remove the class_name declaration to fix this error.");
3699 }
3700 return;
3701 }
3702
3703 tokenizer->advance(2);
3704
3705 if (tokenizer->get_token() == GDScriptTokenizer::TK_COMMA) {
3706 tokenizer->advance();
3707
3708 if ((tokenizer->get_token() == GDScriptTokenizer::TK_CONSTANT && tokenizer->get_token_constant().get_type() == Variant::STRING)) {
3709 #ifdef TOOLS_ENABLED
3710 if (Engine::get_singleton()->is_editor_hint()) {
3711 Variant constant = tokenizer->get_token_constant();
3712 String icon_path = constant.operator String();
3713
3714 String abs_icon_path = icon_path.is_rel_path() ? self_path.get_base_dir().plus_file(icon_path).simplify_path() : icon_path;
3715 if (!FileAccess::exists(abs_icon_path)) {
3716 _set_error("No class icon found at: " + abs_icon_path);
3717 return;
3718 }
3719
3720 p_class->icon_path = icon_path;
3721 }
3722 #endif
3723
3724 tokenizer->advance();
3725 } else {
3726 _set_error("The optional parameter after \"class_name\" must be a string constant file path to an icon.");
3727 return;
3728 }
3729
3730 } else if (tokenizer->get_token() == GDScriptTokenizer::TK_CONSTANT) {
3731 _set_error("The class icon must be separated by a comma.");
3732 return;
3733 }
3734
3735 } break;
3736 case GDScriptTokenizer::TK_PR_TOOL: {
3737
3738 if (p_class->tool) {
3739
3740 _set_error("The \"tool\" keyword can only be present once per script.");
3741 return;
3742 }
3743
3744 p_class->tool = true;
3745 tokenizer->advance();
3746
3747 } break;
3748 case GDScriptTokenizer::TK_PR_CLASS: {
3749 //class inside class :D
3750
3751 StringName name;
3752
3753 if (tokenizer->get_token(1) != GDScriptTokenizer::TK_IDENTIFIER) {
3754
3755 _set_error("\"class\" syntax: \"class <Name>:\" or \"class <Name> extends <BaseClass>:\"");
3756 return;
3757 }
3758 name = tokenizer->get_token_identifier(1);
3759 tokenizer->advance(2);
3760
3761 // Check if name is shadowing something else
3762 if (ClassDB::class_exists(name) || ClassDB::class_exists("_" + name.operator String())) {
3763 _set_error("The class \"" + String(name) + "\" shadows a native class.");
3764 return;
3765 }
3766 if (ScriptServer::is_global_class(name)) {
3767 _set_error("Can't override name of the unique global class \"" + name + "\". It already exists at: " + ScriptServer::get_global_class_path(p_class->name));
3768 return;
3769 }
3770 ClassNode *outer_class = p_class;
3771 while (outer_class) {
3772 for (int i = 0; i < outer_class->subclasses.size(); i++) {
3773 if (outer_class->subclasses[i]->name == name) {
3774 _set_error("Another class named \"" + String(name) + "\" already exists in this scope (at line " + itos(outer_class->subclasses[i]->line) + ").");
3775 return;
3776 }
3777 }
3778 if (outer_class->constant_expressions.has(name)) {
3779 _set_error("A constant named \"" + String(name) + "\" already exists in the outer class scope (at line" + itos(outer_class->constant_expressions[name].expression->line) + ").");
3780 return;
3781 }
3782 for (int i = 0; i < outer_class->variables.size(); i++) {
3783 if (outer_class->variables[i].identifier == name) {
3784 _set_error("A variable named \"" + String(name) + "\" already exists in the outer class scope (at line " + itos(outer_class->variables[i].line) + ").");
3785 return;
3786 }
3787 }
3788
3789 outer_class = outer_class->owner;
3790 }
3791
3792 ClassNode *newclass = alloc_node<ClassNode>();
3793 newclass->initializer = alloc_node<BlockNode>();
3794 newclass->initializer->parent_class = newclass;
3795 newclass->ready = alloc_node<BlockNode>();
3796 newclass->ready->parent_class = newclass;
3797 newclass->name = name;
3798 newclass->owner = p_class;
3799
3800 p_class->subclasses.push_back(newclass);
3801
3802 if (tokenizer->get_token() == GDScriptTokenizer::TK_PR_EXTENDS) {
3803
3804 _parse_extends(newclass);
3805 if (error_set)
3806 return;
3807 }
3808
3809 if (!_enter_indent_block()) {
3810
3811 _set_error("Indented block expected.");
3812 return;
3813 }
3814 current_class = newclass;
3815 _parse_class(newclass);
3816 current_class = p_class;
3817
3818 } break;
3819 /* this is for functions....
3820 case GDScriptTokenizer::TK_CF_PASS: {
3821
3822 tokenizer->advance(1);
3823 } break;
3824 */
3825 case GDScriptTokenizer::TK_PR_STATIC: {
3826 tokenizer->advance();
3827 if (tokenizer->get_token() != GDScriptTokenizer::TK_PR_FUNCTION) {
3828
3829 _set_error("Expected \"func\".");
3830 return;
3831 }
3832
3833 FALLTHROUGH;
3834 }
3835 case GDScriptTokenizer::TK_PR_FUNCTION: {
3836
3837 bool _static = false;
3838 pending_newline = -1;
3839
3840 if (tokenizer->get_token(-1) == GDScriptTokenizer::TK_PR_STATIC) {
3841
3842 _static = true;
3843 }
3844
3845 tokenizer->advance();
3846 StringName name;
3847
3848 if (_get_completable_identifier(COMPLETION_VIRTUAL_FUNC, name)) {
3849 }
3850
3851 if (name == StringName()) {
3852
3853 _set_error("Expected an identifier after \"func\" (syntax: \"func <identifier>([arguments]):\").");
3854 return;
3855 }
3856
3857 for (int i = 0; i < p_class->functions.size(); i++) {
3858 if (p_class->functions[i]->name == name) {
3859 _set_error("The function \"" + String(name) + "\" already exists in this class (at line " + itos(p_class->functions[i]->line) + ").");
3860 }
3861 }
3862 for (int i = 0; i < p_class->static_functions.size(); i++) {
3863 if (p_class->static_functions[i]->name == name) {
3864 _set_error("The function \"" + String(name) + "\" already exists in this class (at line " + itos(p_class->static_functions[i]->line) + ").");
3865 }
3866 }
3867
3868 #ifdef DEBUG_ENABLED
3869 if (p_class->constant_expressions.has(name)) {
3870 _add_warning(GDScriptWarning::FUNCTION_CONFLICTS_CONSTANT, -1, name);
3871 }
3872 for (int i = 0; i < p_class->variables.size(); i++) {
3873 if (p_class->variables[i].identifier == name) {
3874 _add_warning(GDScriptWarning::FUNCTION_CONFLICTS_VARIABLE, -1, name);
3875 }
3876 }
3877 for (int i = 0; i < p_class->subclasses.size(); i++) {
3878 if (p_class->subclasses[i]->name == name) {
3879 _add_warning(GDScriptWarning::FUNCTION_CONFLICTS_CONSTANT, -1, name);
3880 }
3881 }
3882 #endif // DEBUG_ENABLED
3883
3884 if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_OPEN) {
3885
3886 _set_error("Expected \"(\" after the identifier (syntax: \"func <identifier>([arguments]):\" ).");
3887 return;
3888 }
3889
3890 tokenizer->advance();
3891
3892 Vector<StringName> arguments;
3893 Vector<DataType> argument_types;
3894 Vector<Node *> default_values;
3895 #ifdef DEBUG_ENABLED
3896 Vector<int> arguments_usage;
3897 #endif // DEBUG_ENABLED
3898
3899 int fnline = tokenizer->get_token_line();
3900
3901 if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_CLOSE) {
3902 //has arguments
3903 bool defaulting = false;
3904 while (true) {
3905
3906 if (tokenizer->get_token() == GDScriptTokenizer::TK_NEWLINE) {
3907 tokenizer->advance();
3908 continue;
3909 }
3910
3911 if (tokenizer->get_token() == GDScriptTokenizer::TK_PR_VAR) {
3912
3913 tokenizer->advance(); //var before the identifier is allowed
3914 }
3915
3916 if (!tokenizer->is_token_literal(0, true)) {
3917
3918 _set_error("Expected an identifier for an argument.");
3919 return;
3920 }
3921
3922 StringName argname = tokenizer->get_token_identifier();
3923 for (int i = 0; i < arguments.size(); i++) {
3924 if (arguments[i] == argname) {
3925 _set_error("The argument name \"" + String(argname) + "\" is defined multiple times.");
3926 return;
3927 }
3928 }
3929 arguments.push_back(argname);
3930 #ifdef DEBUG_ENABLED
3931 arguments_usage.push_back(0);
3932 #endif // DEBUG_ENABLED
3933
3934 tokenizer->advance();
3935
3936 DataType argtype;
3937 if (tokenizer->get_token() == GDScriptTokenizer::TK_COLON) {
3938 if (tokenizer->get_token(1) == GDScriptTokenizer::TK_OP_ASSIGN) {
3939 argtype.infer_type = true;
3940 tokenizer->advance();
3941 } else if (!_parse_type(argtype)) {
3942 _set_error("Expected a type for an argument.");
3943 return;
3944 }
3945 }
3946 argument_types.push_back(argtype);
3947
3948 if (defaulting && tokenizer->get_token() != GDScriptTokenizer::TK_OP_ASSIGN) {
3949
3950 _set_error("Default parameter expected.");
3951 return;
3952 }
3953
3954 //tokenizer->advance();
3955
3956 if (tokenizer->get_token() == GDScriptTokenizer::TK_OP_ASSIGN) {
3957 defaulting = true;
3958 tokenizer->advance(1);
3959 Node *defval = _parse_and_reduce_expression(p_class, _static);
3960 if (!defval || error_set)
3961 return;
3962
3963 OperatorNode *on = alloc_node<OperatorNode>();
3964 on->op = OperatorNode::OP_ASSIGN;
3965 on->line = fnline;
3966
3967 IdentifierNode *in = alloc_node<IdentifierNode>();
3968 in->name = argname;
3969 in->line = fnline;
3970
3971 on->arguments.push_back(in);
3972 on->arguments.push_back(defval);
3973 /* no ..
3974 if (defval->type!=Node::TYPE_CONSTANT) {
3975
3976 _set_error("default argument must be constant");
3977 }
3978 */
3979 default_values.push_back(on);
3980 }
3981
3982 while (tokenizer->get_token() == GDScriptTokenizer::TK_NEWLINE) {
3983 tokenizer->advance();
3984 }
3985
3986 if (tokenizer->get_token() == GDScriptTokenizer::TK_COMMA) {
3987 tokenizer->advance();
3988 continue;
3989 } else if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_CLOSE) {
3990
3991 _set_error("Expected \",\" or \")\".");
3992 return;
3993 }
3994
3995 break;
3996 }
3997 }
3998
3999 tokenizer->advance();
4000
4001 BlockNode *block = alloc_node<BlockNode>();
4002 block->parent_class = p_class;
4003
4004 FunctionNode *function = alloc_node<FunctionNode>();
4005 function->name = name;
4006 function->arguments = arguments;
4007 function->argument_types = argument_types;
4008 function->default_values = default_values;
4009 function->_static = _static;
4010 function->line = fnline;
4011 #ifdef DEBUG_ENABLED
4012 function->arguments_usage = arguments_usage;
4013 #endif // DEBUG_ENABLED
4014 function->rpc_mode = rpc_mode;
4015 rpc_mode = MultiplayerAPI::RPC_MODE_DISABLED;
4016
4017 if (name == "_init") {
4018
4019 if (_static) {
4020 _set_error("The constructor cannot be static.");
4021 return;
4022 }
4023
4024 if (p_class->extends_used) {
4025
4026 OperatorNode *cparent = alloc_node<OperatorNode>();
4027 cparent->op = OperatorNode::OP_PARENT_CALL;
4028 block->statements.push_back(cparent);
4029
4030 IdentifierNode *id = alloc_node<IdentifierNode>();
4031 id->name = "_init";
4032 cparent->arguments.push_back(id);
4033
4034 if (tokenizer->get_token() == GDScriptTokenizer::TK_PERIOD) {
4035 tokenizer->advance();
4036 if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_OPEN) {
4037 _set_error("Expected \"(\" for parent constructor arguments.");
4038 return;
4039 }
4040 tokenizer->advance();
4041
4042 if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_CLOSE) {
4043 //has arguments
4044 parenthesis++;
4045 while (true) {
4046
4047 current_function = function;
4048 Node *arg = _parse_and_reduce_expression(p_class, _static);
4049 if (!arg) {
4050 return;
4051 }
4052 current_function = NULL;
4053 cparent->arguments.push_back(arg);
4054
4055 if (tokenizer->get_token() == GDScriptTokenizer::TK_COMMA) {
4056 tokenizer->advance();
4057 continue;
4058 } else if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_CLOSE) {
4059
4060 _set_error("Expected \",\" or \")\".");
4061 return;
4062 }
4063
4064 break;
4065 }
4066 parenthesis--;
4067 }
4068
4069 tokenizer->advance();
4070 }
4071 } else {
4072
4073 if (tokenizer->get_token() == GDScriptTokenizer::TK_PERIOD) {
4074
4075 _set_error("Parent constructor call found for a class without inheritance.");
4076 return;
4077 }
4078 }
4079 }
4080
4081 DataType return_type;
4082 if (tokenizer->get_token() == GDScriptTokenizer::TK_FORWARD_ARROW) {
4083
4084 if (!_parse_type(return_type, true)) {
4085 _set_error("Expected a return type for the function.");
4086 return;
4087 }
4088 }
4089
4090 if (!_enter_indent_block(block)) {
4091
4092 _set_error(vformat("Indented block expected after declaration of \"%s\" function.", function->name));
4093 return;
4094 }
4095
4096 function->return_type = return_type;
4097
4098 if (_static)
4099 p_class->static_functions.push_back(function);
4100 else
4101 p_class->functions.push_back(function);
4102
4103 current_function = function;
4104 function->body = block;
4105 current_block = block;
4106 _parse_block(block, _static);
4107 current_block = NULL;
4108
4109 //arguments
4110 } break;
4111 case GDScriptTokenizer::TK_PR_SIGNAL: {
4112 tokenizer->advance();
4113
4114 if (!tokenizer->is_token_literal()) {
4115 _set_error("Expected an identifier after \"signal\".");
4116 return;
4117 }
4118
4119 ClassNode::Signal sig;
4120 sig.name = tokenizer->get_token_identifier();
4121 sig.emissions = 0;
4122 sig.line = tokenizer->get_token_line();
4123
4124 for (int i = 0; i < current_class->_signals.size(); i++) {
4125 if (current_class->_signals[i].name == sig.name) {
4126 _set_error("The signal \"" + sig.name + "\" already exists in this class (at line: " + itos(current_class->_signals[i].line) + ").");
4127 return;
4128 }
4129 }
4130
4131 tokenizer->advance();
4132
4133 if (tokenizer->get_token() == GDScriptTokenizer::TK_PARENTHESIS_OPEN) {
4134 tokenizer->advance();
4135 while (true) {
4136 if (tokenizer->get_token() == GDScriptTokenizer::TK_NEWLINE) {
4137 tokenizer->advance();
4138 continue;
4139 }
4140
4141 if (tokenizer->get_token() == GDScriptTokenizer::TK_PARENTHESIS_CLOSE) {
4142 tokenizer->advance();
4143 break;
4144 }
4145
4146 if (!tokenizer->is_token_literal(0, true)) {
4147 _set_error("Expected an identifier in a \"signal\" argument.");
4148 return;
4149 }
4150
4151 sig.arguments.push_back(tokenizer->get_token_identifier());
4152 tokenizer->advance();
4153
4154 while (tokenizer->get_token() == GDScriptTokenizer::TK_NEWLINE) {
4155 tokenizer->advance();
4156 }
4157
4158 if (tokenizer->get_token() == GDScriptTokenizer::TK_COMMA) {
4159 tokenizer->advance();
4160 } else if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_CLOSE) {
4161 _set_error("Expected \",\" or \")\" after a \"signal\" parameter identifier.");
4162 return;
4163 }
4164 }
4165 }
4166
4167 p_class->_signals.push_back(sig);
4168
4169 if (!_end_statement()) {
4170 _set_end_statement_error("signal");
4171 return;
4172 }
4173 } break;
4174 case GDScriptTokenizer::TK_PR_EXPORT: {
4175
4176 tokenizer->advance();
4177
4178 if (tokenizer->get_token() == GDScriptTokenizer::TK_PARENTHESIS_OPEN) {
4179
4180 #define _ADVANCE_AND_CONSUME_NEWLINES \
4181 do { \
4182 tokenizer->advance(); \
4183 } while (tokenizer->get_token() == GDScriptTokenizer::TK_NEWLINE)
4184
4185 _ADVANCE_AND_CONSUME_NEWLINES;
4186 parenthesis++;
4187
4188 String hint_prefix = "";
4189 bool is_arrayed = false;
4190
4191 while (tokenizer->get_token() == GDScriptTokenizer::TK_BUILT_IN_TYPE &&
4192 tokenizer->get_token_type() == Variant::ARRAY &&
4193 tokenizer->get_token(1) == GDScriptTokenizer::TK_COMMA) {
4194 tokenizer->advance(); // Array
4195 tokenizer->advance(); // Comma
4196 if (is_arrayed) {
4197 hint_prefix += itos(Variant::ARRAY) + ":";
4198 } else {
4199 is_arrayed = true;
4200 }
4201 }
4202
4203 if (tokenizer->get_token() == GDScriptTokenizer::TK_BUILT_IN_TYPE) {
4204
4205 Variant::Type type = tokenizer->get_token_type();
4206 if (type == Variant::NIL) {
4207 _set_error("Can't export null type.");
4208 return;
4209 }
4210 if (type == Variant::OBJECT) {
4211 _set_error("Can't export raw object type.");
4212 return;
4213 }
4214 current_export.type = type;
4215 current_export.usage |= PROPERTY_USAGE_SCRIPT_VARIABLE;
4216 _ADVANCE_AND_CONSUME_NEWLINES;
4217
4218 if (tokenizer->get_token() == GDScriptTokenizer::TK_COMMA) {
4219 // hint expected next!
4220 _ADVANCE_AND_CONSUME_NEWLINES;
4221
4222 switch (type) {
4223
4224 case Variant::INT: {
4225
4226 if (tokenizer->get_token() == GDScriptTokenizer::TK_IDENTIFIER && tokenizer->get_token_identifier() == "FLAGS") {
4227
4228 _ADVANCE_AND_CONSUME_NEWLINES;
4229
4230 if (tokenizer->get_token() == GDScriptTokenizer::TK_PARENTHESIS_CLOSE) {
4231 WARN_DEPRECATED_MSG("Exporting bit flags hint requires string constants.");
4232 break;
4233 }
4234 if (tokenizer->get_token() != GDScriptTokenizer::TK_COMMA) {
4235 _set_error("Expected \",\" in the bit flags hint.");
4236 return;
4237 }
4238
4239 current_export.hint = PROPERTY_HINT_FLAGS;
4240 _ADVANCE_AND_CONSUME_NEWLINES;
4241
4242 bool first = true;
4243 while (true) {
4244
4245 if (tokenizer->get_token() != GDScriptTokenizer::TK_CONSTANT || tokenizer->get_token_constant().get_type() != Variant::STRING) {
4246 current_export = PropertyInfo();
4247 _set_error("Expected a string constant in the named bit flags hint.");
4248 return;
4249 }
4250
4251 String c = tokenizer->get_token_constant();
4252 if (!first)
4253 current_export.hint_string += ",";
4254 else
4255 first = false;
4256
4257 current_export.hint_string += c.xml_escape();
4258
4259 _ADVANCE_AND_CONSUME_NEWLINES;
4260 if (tokenizer->get_token() == GDScriptTokenizer::TK_PARENTHESIS_CLOSE)
4261 break;
4262
4263 if (tokenizer->get_token() != GDScriptTokenizer::TK_COMMA) {
4264 current_export = PropertyInfo();
4265 _set_error("Expected \")\" or \",\" in the named bit flags hint.");
4266 return;
4267 }
4268 _ADVANCE_AND_CONSUME_NEWLINES;
4269 }
4270
4271 break;
4272 }
4273
4274 if (tokenizer->get_token() == GDScriptTokenizer::TK_IDENTIFIER && tokenizer->get_token_identifier() == "LAYERS_2D_RENDER") {
4275
4276 _ADVANCE_AND_CONSUME_NEWLINES;
4277 if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_CLOSE) {
4278 _set_error("Expected \")\" in the layers 2D render hint.");
4279 return;
4280 }
4281 current_export.hint = PROPERTY_HINT_LAYERS_2D_RENDER;
4282 break;
4283 }
4284
4285 if (tokenizer->get_token() == GDScriptTokenizer::TK_IDENTIFIER && tokenizer->get_token_identifier() == "LAYERS_2D_PHYSICS") {
4286
4287 _ADVANCE_AND_CONSUME_NEWLINES;
4288 if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_CLOSE) {
4289 _set_error("Expected \")\" in the layers 2D physics hint.");
4290 return;
4291 }
4292 current_export.hint = PROPERTY_HINT_LAYERS_2D_PHYSICS;
4293 break;
4294 }
4295
4296 if (tokenizer->get_token() == GDScriptTokenizer::TK_IDENTIFIER && tokenizer->get_token_identifier() == "LAYERS_3D_RENDER") {
4297
4298 _ADVANCE_AND_CONSUME_NEWLINES;
4299 if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_CLOSE) {
4300 _set_error("Expected \")\" in the layers 3D render hint.");
4301 return;
4302 }
4303 current_export.hint = PROPERTY_HINT_LAYERS_3D_RENDER;
4304 break;
4305 }
4306
4307 if (tokenizer->get_token() == GDScriptTokenizer::TK_IDENTIFIER && tokenizer->get_token_identifier() == "LAYERS_3D_PHYSICS") {
4308
4309 _ADVANCE_AND_CONSUME_NEWLINES;
4310 if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_CLOSE) {
4311 _set_error("Expected \")\" in the layers 3D physics hint.");
4312 return;
4313 }
4314 current_export.hint = PROPERTY_HINT_LAYERS_3D_PHYSICS;
4315 break;
4316 }
4317
4318 if (tokenizer->get_token() == GDScriptTokenizer::TK_CONSTANT && tokenizer->get_token_constant().get_type() == Variant::STRING) {
4319 //enumeration
4320 current_export.hint = PROPERTY_HINT_ENUM;
4321 bool first = true;
4322 while (true) {
4323
4324 if (tokenizer->get_token() != GDScriptTokenizer::TK_CONSTANT || tokenizer->get_token_constant().get_type() != Variant::STRING) {
4325
4326 current_export = PropertyInfo();
4327 _set_error("Expected a string constant in the enumeration hint.");
4328 return;
4329 }
4330
4331 String c = tokenizer->get_token_constant();
4332 if (!first)
4333 current_export.hint_string += ",";
4334 else
4335 first = false;
4336
4337 current_export.hint_string += c.xml_escape();
4338
4339 _ADVANCE_AND_CONSUME_NEWLINES;
4340 if (tokenizer->get_token() == GDScriptTokenizer::TK_PARENTHESIS_CLOSE)
4341 break;
4342
4343 if (tokenizer->get_token() != GDScriptTokenizer::TK_COMMA) {
4344 current_export = PropertyInfo();
4345 _set_error("Expected \")\" or \",\" in the enumeration hint.");
4346 return;
4347 }
4348
4349 _ADVANCE_AND_CONSUME_NEWLINES;
4350 }
4351
4352 break;
4353 }
4354
4355 FALLTHROUGH;
4356 }
4357 case Variant::REAL: {
4358
4359 if (tokenizer->get_token() == GDScriptTokenizer::TK_IDENTIFIER && tokenizer->get_token_identifier() == "EASE") {
4360 current_export.hint = PROPERTY_HINT_EXP_EASING;
4361 _ADVANCE_AND_CONSUME_NEWLINES;
4362 if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_CLOSE) {
4363 _set_error("Expected \")\" in the hint.");
4364 return;
4365 }
4366 break;
4367 }
4368
4369 // range
4370 if (tokenizer->get_token() == GDScriptTokenizer::TK_IDENTIFIER && tokenizer->get_token_identifier() == "EXP") {
4371
4372 current_export.hint = PROPERTY_HINT_EXP_RANGE;
4373 _ADVANCE_AND_CONSUME_NEWLINES;
4374
4375 if (tokenizer->get_token() == GDScriptTokenizer::TK_PARENTHESIS_CLOSE)
4376 break;
4377 else if (tokenizer->get_token() != GDScriptTokenizer::TK_COMMA) {
4378 _set_error("Expected \")\" or \",\" in the exponential range hint.");
4379 return;
4380 }
4381 _ADVANCE_AND_CONSUME_NEWLINES;
4382 } else
4383 current_export.hint = PROPERTY_HINT_RANGE;
4384
4385 float sign = 1.0;
4386
4387 if (tokenizer->get_token() == GDScriptTokenizer::TK_OP_SUB) {
4388 sign = -1;
4389 _ADVANCE_AND_CONSUME_NEWLINES;
4390 }
4391 if (tokenizer->get_token() != GDScriptTokenizer::TK_CONSTANT || !tokenizer->get_token_constant().is_num()) {
4392
4393 current_export = PropertyInfo();
4394 _set_error("Expected a range in the numeric hint.");
4395 return;
4396 }
4397
4398 current_export.hint_string = rtos(sign * double(tokenizer->get_token_constant()));
4399 _ADVANCE_AND_CONSUME_NEWLINES;
4400
4401 if (tokenizer->get_token() == GDScriptTokenizer::TK_PARENTHESIS_CLOSE) {
4402 current_export.hint_string = "0," + current_export.hint_string;
4403 break;
4404 }
4405
4406 if (tokenizer->get_token() != GDScriptTokenizer::TK_COMMA) {
4407
4408 current_export = PropertyInfo();
4409 _set_error("Expected \",\" or \")\" in the numeric range hint.");
4410 return;
4411 }
4412
4413 _ADVANCE_AND_CONSUME_NEWLINES;
4414
4415 sign = 1.0;
4416 if (tokenizer->get_token() == GDScriptTokenizer::TK_OP_SUB) {
4417 sign = -1;
4418 _ADVANCE_AND_CONSUME_NEWLINES;
4419 }
4420
4421 if (tokenizer->get_token() != GDScriptTokenizer::TK_CONSTANT || !tokenizer->get_token_constant().is_num()) {
4422
4423 current_export = PropertyInfo();
4424 _set_error("Expected a number as upper bound in the numeric range hint.");
4425 return;
4426 }
4427
4428 current_export.hint_string += "," + rtos(sign * double(tokenizer->get_token_constant()));
4429 _ADVANCE_AND_CONSUME_NEWLINES;
4430
4431 if (tokenizer->get_token() == GDScriptTokenizer::TK_PARENTHESIS_CLOSE)
4432 break;
4433
4434 if (tokenizer->get_token() != GDScriptTokenizer::TK_COMMA) {
4435
4436 current_export = PropertyInfo();
4437 _set_error("Expected \",\" or \")\" in the numeric range hint.");
4438 return;
4439 }
4440
4441 _ADVANCE_AND_CONSUME_NEWLINES;
4442 sign = 1.0;
4443 if (tokenizer->get_token() == GDScriptTokenizer::TK_OP_SUB) {
4444 sign = -1;
4445 _ADVANCE_AND_CONSUME_NEWLINES;
4446 }
4447
4448 if (tokenizer->get_token() != GDScriptTokenizer::TK_CONSTANT || !tokenizer->get_token_constant().is_num()) {
4449
4450 current_export = PropertyInfo();
4451 _set_error("Expected a number as step in the numeric range hint.");
4452 return;
4453 }
4454
4455 current_export.hint_string += "," + rtos(sign * double(tokenizer->get_token_constant()));
4456 _ADVANCE_AND_CONSUME_NEWLINES;
4457
4458 } break;
4459 case Variant::STRING: {
4460
4461 if (tokenizer->get_token() == GDScriptTokenizer::TK_CONSTANT && tokenizer->get_token_constant().get_type() == Variant::STRING) {
4462 //enumeration
4463 current_export.hint = PROPERTY_HINT_ENUM;
4464 bool first = true;
4465 while (true) {
4466
4467 if (tokenizer->get_token() != GDScriptTokenizer::TK_CONSTANT || tokenizer->get_token_constant().get_type() != Variant::STRING) {
4468
4469 current_export = PropertyInfo();
4470 _set_error("Expected a string constant in the enumeration hint.");
4471 return;
4472 }
4473
4474 String c = tokenizer->get_token_constant();
4475 if (!first)
4476 current_export.hint_string += ",";
4477 else
4478 first = false;
4479
4480 current_export.hint_string += c.xml_escape();
4481 _ADVANCE_AND_CONSUME_NEWLINES;
4482 if (tokenizer->get_token() == GDScriptTokenizer::TK_PARENTHESIS_CLOSE)
4483 break;
4484
4485 if (tokenizer->get_token() != GDScriptTokenizer::TK_COMMA) {
4486 current_export = PropertyInfo();
4487 _set_error("Expected \")\" or \",\" in the enumeration hint.");
4488 return;
4489 }
4490 _ADVANCE_AND_CONSUME_NEWLINES;
4491 }
4492
4493 break;
4494 }
4495
4496 if (tokenizer->get_token() == GDScriptTokenizer::TK_IDENTIFIER && tokenizer->get_token_identifier() == "DIR") {
4497
4498 _ADVANCE_AND_CONSUME_NEWLINES;
4499
4500 if (tokenizer->get_token() == GDScriptTokenizer::TK_PARENTHESIS_CLOSE)
4501 current_export.hint = PROPERTY_HINT_DIR;
4502 else if (tokenizer->get_token() == GDScriptTokenizer::TK_COMMA) {
4503
4504 _ADVANCE_AND_CONSUME_NEWLINES;
4505
4506 if (tokenizer->get_token() != GDScriptTokenizer::TK_IDENTIFIER || !(tokenizer->get_token_identifier() == "GLOBAL")) {
4507 _set_error("Expected \"GLOBAL\" after comma in the directory hint.");
4508 return;
4509 }
4510 if (!p_class->tool) {
4511 _set_error("Global filesystem hints may only be used in tool scripts.");
4512 return;
4513 }
4514 current_export.hint = PROPERTY_HINT_GLOBAL_DIR;
4515 _ADVANCE_AND_CONSUME_NEWLINES;
4516
4517 if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_CLOSE) {
4518 _set_error("Expected \")\" in the hint.");
4519 return;
4520 }
4521 } else {
4522 _set_error("Expected \")\" or \",\" in the hint.");
4523 return;
4524 }
4525 break;
4526 }
4527
4528 if (tokenizer->get_token() == GDScriptTokenizer::TK_IDENTIFIER && tokenizer->get_token_identifier() == "FILE") {
4529
4530 current_export.hint = PROPERTY_HINT_FILE;
4531 _ADVANCE_AND_CONSUME_NEWLINES;
4532
4533 if (tokenizer->get_token() == GDScriptTokenizer::TK_COMMA) {
4534
4535 _ADVANCE_AND_CONSUME_NEWLINES;
4536
4537 if (tokenizer->get_token() == GDScriptTokenizer::TK_IDENTIFIER && tokenizer->get_token_identifier() == "GLOBAL") {
4538
4539 if (!p_class->tool) {
4540 _set_error("Global filesystem hints may only be used in tool scripts.");
4541 return;
4542 }
4543 current_export.hint = PROPERTY_HINT_GLOBAL_FILE;
4544 _ADVANCE_AND_CONSUME_NEWLINES;
4545
4546 if (tokenizer->get_token() == GDScriptTokenizer::TK_PARENTHESIS_CLOSE)
4547 break;
4548 else if (tokenizer->get_token() == GDScriptTokenizer::TK_COMMA)
4549 _ADVANCE_AND_CONSUME_NEWLINES;
4550 else {
4551 _set_error("Expected \")\" or \",\" in the hint.");
4552 return;
4553 }
4554 }
4555
4556 if (tokenizer->get_token() != GDScriptTokenizer::TK_CONSTANT || tokenizer->get_token_constant().get_type() != Variant::STRING) {
4557
4558 if (current_export.hint == PROPERTY_HINT_GLOBAL_FILE)
4559 _set_error("Expected string constant with filter.");
4560 else
4561 _set_error("Expected \"GLOBAL\" or string constant with filter.");
4562 return;
4563 }
4564 current_export.hint_string = tokenizer->get_token_constant();
4565 _ADVANCE_AND_CONSUME_NEWLINES;
4566 }
4567
4568 if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_CLOSE) {
4569 _set_error("Expected \")\" in the hint.");
4570 return;
4571 }
4572 break;
4573 }
4574
4575 if (tokenizer->get_token() == GDScriptTokenizer::TK_IDENTIFIER && tokenizer->get_token_identifier() == "MULTILINE") {
4576
4577 current_export.hint = PROPERTY_HINT_MULTILINE_TEXT;
4578 _ADVANCE_AND_CONSUME_NEWLINES;
4579 if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_CLOSE) {
4580 _set_error("Expected \")\" in the hint.");
4581 return;
4582 }
4583 break;
4584 }
4585 } break;
4586 case Variant::COLOR: {
4587
4588 if (tokenizer->get_token() != GDScriptTokenizer::TK_IDENTIFIER) {
4589
4590 current_export = PropertyInfo();
4591 _set_error("Color type hint expects RGB or RGBA as hints.");
4592 return;
4593 }
4594
4595 String identifier = tokenizer->get_token_identifier();
4596 if (identifier == "RGB") {
4597 current_export.hint = PROPERTY_HINT_COLOR_NO_ALPHA;
4598 } else if (identifier == "RGBA") {
4599 //none
4600 } else {
4601 current_export = PropertyInfo();
4602 _set_error("Color type hint expects RGB or RGBA as hints.");
4603 return;
4604 }
4605 _ADVANCE_AND_CONSUME_NEWLINES;
4606
4607 } break;
4608 default: {
4609
4610 current_export = PropertyInfo();
4611 _set_error("Type \"" + Variant::get_type_name(type) + "\" can't take hints.");
4612 return;
4613 } break;
4614 }
4615 }
4616
4617 } else {
4618
4619 parenthesis++;
4620 Node *subexpr = _parse_and_reduce_expression(p_class, true, true);
4621 if (!subexpr) {
4622 if (_recover_from_completion()) {
4623 break;
4624 }
4625 return;
4626 }
4627 parenthesis--;
4628
4629 if (subexpr->type != Node::TYPE_CONSTANT) {
4630 current_export = PropertyInfo();
4631 _set_error("Expected a constant expression.");
4632 }
4633
4634 Variant constant = static_cast<ConstantNode *>(subexpr)->value;
4635
4636 if (constant.get_type() == Variant::OBJECT) {
4637 GDScriptNativeClass *native_class = Object::cast_to<GDScriptNativeClass>(constant);
4638
4639 if (native_class && ClassDB::is_parent_class(native_class->get_name(), "Resource")) {
4640 current_export.type = Variant::OBJECT;
4641 current_export.hint = PROPERTY_HINT_RESOURCE_TYPE;
4642 current_export.usage |= PROPERTY_USAGE_SCRIPT_VARIABLE;
4643
4644 current_export.hint_string = native_class->get_name();
4645 current_export.class_name = native_class->get_name();
4646
4647 } else {
4648 current_export = PropertyInfo();
4649 _set_error("The export hint isn't a resource type.");
4650 }
4651 } else if (constant.get_type() == Variant::DICTIONARY) {
4652 // Enumeration
4653 bool is_flags = false;
4654
4655 if (tokenizer->get_token() == GDScriptTokenizer::TK_COMMA) {
4656 _ADVANCE_AND_CONSUME_NEWLINES;
4657
4658 if (tokenizer->get_token() == GDScriptTokenizer::TK_IDENTIFIER && tokenizer->get_token_identifier() == "FLAGS") {
4659 is_flags = true;
4660 _ADVANCE_AND_CONSUME_NEWLINES;
4661 } else {
4662 current_export = PropertyInfo();
4663 _set_error("Expected \"FLAGS\" after comma.");
4664 }
4665 }
4666
4667 current_export.type = Variant::INT;
4668 current_export.hint = is_flags ? PROPERTY_HINT_FLAGS : PROPERTY_HINT_ENUM;
4669 current_export.usage |= PROPERTY_USAGE_SCRIPT_VARIABLE;
4670 Dictionary enum_values = constant;
4671
4672 List<Variant> keys;
4673 enum_values.get_key_list(&keys);
4674
4675 bool first = true;
4676 for (List<Variant>::Element *E = keys.front(); E; E = E->next()) {
4677 if (enum_values[E->get()].get_type() == Variant::INT) {
4678 if (!first)
4679 current_export.hint_string += ",";
4680 else
4681 first = false;
4682
4683 current_export.hint_string += E->get().operator String().camelcase_to_underscore(true).capitalize().xml_escape();
4684 if (!is_flags) {
4685 current_export.hint_string += ":";
4686 current_export.hint_string += enum_values[E->get()].operator String().xml_escape();
4687 }
4688 }
4689 }
4690 } else {
4691 current_export = PropertyInfo();
4692 _set_error("Expected type for export.");
4693 return;
4694 }
4695 }
4696
4697 if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_CLOSE) {
4698
4699 current_export = PropertyInfo();
4700 _set_error("Expected \")\" or \",\" after the export hint.");
4701 return;
4702 }
4703
4704 tokenizer->advance();
4705 parenthesis--;
4706
4707 if (is_arrayed) {
4708 hint_prefix += itos(current_export.type);
4709 if (current_export.hint) {
4710 hint_prefix += "/" + itos(current_export.hint);
4711 }
4712 current_export.hint_string = hint_prefix + ":" + current_export.hint_string;
4713 current_export.hint = PROPERTY_HINT_TYPE_STRING;
4714 current_export.type = Variant::ARRAY;
4715 }
4716 #undef _ADVANCE_AND_CONSUME_NEWLINES
4717 }
4718
4719 if (tokenizer->get_token() != GDScriptTokenizer::TK_PR_VAR && tokenizer->get_token() != GDScriptTokenizer::TK_PR_ONREADY && tokenizer->get_token() != GDScriptTokenizer::TK_PR_REMOTE && tokenizer->get_token() != GDScriptTokenizer::TK_PR_MASTER && tokenizer->get_token() != GDScriptTokenizer::TK_PR_PUPPET && tokenizer->get_token() != GDScriptTokenizer::TK_PR_SYNC && tokenizer->get_token() != GDScriptTokenizer::TK_PR_REMOTESYNC && tokenizer->get_token() != GDScriptTokenizer::TK_PR_MASTERSYNC && tokenizer->get_token() != GDScriptTokenizer::TK_PR_PUPPETSYNC && tokenizer->get_token() != GDScriptTokenizer::TK_PR_SLAVE) {
4720
4721 current_export = PropertyInfo();
4722 _set_error("Expected \"var\", \"onready\", \"remote\", \"master\", \"puppet\", \"sync\", \"remotesync\", \"mastersync\", \"puppetsync\".");
4723 return;
4724 }
4725
4726 continue;
4727 } break;
4728 case GDScriptTokenizer::TK_PR_ONREADY: {
4729
4730 //may be fallthrough from export, ignore if so
4731 tokenizer->advance();
4732 if (tokenizer->get_token() != GDScriptTokenizer::TK_PR_VAR) {
4733 _set_error("Expected \"var\".");
4734 return;
4735 }
4736
4737 continue;
4738 } break;
4739 case GDScriptTokenizer::TK_PR_REMOTE: {
4740
4741 //may be fallthrough from export, ignore if so
4742 tokenizer->advance();
4743 if (current_export.type) {
4744 if (tokenizer->get_token() != GDScriptTokenizer::TK_PR_VAR) {
4745 _set_error("Expected \"var\".");
4746 return;
4747 }
4748
4749 } else {
4750 if (tokenizer->get_token() != GDScriptTokenizer::TK_PR_VAR && tokenizer->get_token() != GDScriptTokenizer::TK_PR_FUNCTION) {
4751 _set_error("Expected \"var\" or \"func\".");
4752 return;
4753 }
4754 }
4755 rpc_mode = MultiplayerAPI::RPC_MODE_REMOTE;
4756
4757 continue;
4758 } break;
4759 case GDScriptTokenizer::TK_PR_MASTER: {
4760
4761 //may be fallthrough from export, ignore if so
4762 tokenizer->advance();
4763 if (current_export.type) {
4764 if (tokenizer->get_token() != GDScriptTokenizer::TK_PR_VAR) {
4765 _set_error("Expected \"var\".");
4766 return;
4767 }
4768
4769 } else {
4770 if (tokenizer->get_token() != GDScriptTokenizer::TK_PR_VAR && tokenizer->get_token() != GDScriptTokenizer::TK_PR_FUNCTION) {
4771 _set_error("Expected \"var\" or \"func\".");
4772 return;
4773 }
4774 }
4775
4776 rpc_mode = MultiplayerAPI::RPC_MODE_MASTER;
4777 continue;
4778 } break;
4779 case GDScriptTokenizer::TK_PR_SLAVE:
4780 #ifdef DEBUG_ENABLED
4781 _add_warning(GDScriptWarning::DEPRECATED_KEYWORD, tokenizer->get_token_line(), "slave", "puppet");
4782 #endif
4783 FALLTHROUGH;
4784 case GDScriptTokenizer::TK_PR_PUPPET: {
4785
4786 //may be fallthrough from export, ignore if so
4787 tokenizer->advance();
4788 if (current_export.type) {
4789 if (tokenizer->get_token() != GDScriptTokenizer::TK_PR_VAR) {
4790 _set_error("Expected \"var\".");
4791 return;
4792 }
4793
4794 } else {
4795 if (tokenizer->get_token() != GDScriptTokenizer::TK_PR_VAR && tokenizer->get_token() != GDScriptTokenizer::TK_PR_FUNCTION) {
4796 _set_error("Expected \"var\" or \"func\".");
4797 return;
4798 }
4799 }
4800
4801 rpc_mode = MultiplayerAPI::RPC_MODE_PUPPET;
4802 continue;
4803 } break;
4804 case GDScriptTokenizer::TK_PR_REMOTESYNC:
4805 case GDScriptTokenizer::TK_PR_SYNC: {
4806
4807 //may be fallthrough from export, ignore if so
4808 tokenizer->advance();
4809 if (tokenizer->get_token() != GDScriptTokenizer::TK_PR_VAR && tokenizer->get_token() != GDScriptTokenizer::TK_PR_FUNCTION) {
4810 if (current_export.type)
4811 _set_error("Expected \"var\".");
4812 else
4813 _set_error("Expected \"var\" or \"func\".");
4814 return;
4815 }
4816
4817 rpc_mode = MultiplayerAPI::RPC_MODE_REMOTESYNC;
4818 continue;
4819 } break;
4820 case GDScriptTokenizer::TK_PR_MASTERSYNC: {
4821
4822 //may be fallthrough from export, ignore if so
4823 tokenizer->advance();
4824 if (tokenizer->get_token() != GDScriptTokenizer::TK_PR_VAR && tokenizer->get_token() != GDScriptTokenizer::TK_PR_FUNCTION) {
4825 if (current_export.type)
4826 _set_error("Expected \"var\".");
4827 else
4828 _set_error("Expected \"var\" or \"func\".");
4829 return;
4830 }
4831
4832 rpc_mode = MultiplayerAPI::RPC_MODE_MASTERSYNC;
4833 continue;
4834 } break;
4835 case GDScriptTokenizer::TK_PR_PUPPETSYNC: {
4836
4837 //may be fallthrough from export, ignore if so
4838 tokenizer->advance();
4839 if (tokenizer->get_token() != GDScriptTokenizer::TK_PR_VAR && tokenizer->get_token() != GDScriptTokenizer::TK_PR_FUNCTION) {
4840 if (current_export.type)
4841 _set_error("Expected \"var\".");
4842 else
4843 _set_error("Expected \"var\" or \"func\".");
4844 return;
4845 }
4846
4847 rpc_mode = MultiplayerAPI::RPC_MODE_PUPPETSYNC;
4848 continue;
4849 } break;
4850 case GDScriptTokenizer::TK_PR_VAR: {
4851 // variable declaration and (eventual) initialization
4852
4853 ClassNode::Member member;
4854
4855 bool autoexport = tokenizer->get_token(-1) == GDScriptTokenizer::TK_PR_EXPORT;
4856 if (current_export.type != Variant::NIL) {
4857 member._export = current_export;
4858 current_export = PropertyInfo();
4859 }
4860
4861 bool onready = tokenizer->get_token(-1) == GDScriptTokenizer::TK_PR_ONREADY;
4862
4863 tokenizer->advance();
4864 if (!tokenizer->is_token_literal(0, true)) {
4865
4866 _set_error("Expected an identifier for the member variable name.");
4867 return;
4868 }
4869
4870 member.identifier = tokenizer->get_token_literal();
4871 member.expression = NULL;
4872 member._export.name = member.identifier;
4873 member.line = tokenizer->get_token_line();
4874 member.usages = 0;
4875 member.rpc_mode = rpc_mode;
4876
4877 if (current_class->constant_expressions.has(member.identifier)) {
4878 _set_error("A constant named \"" + String(member.identifier) + "\" already exists in this class (at line: " +
4879 itos(current_class->constant_expressions[member.identifier].expression->line) + ").");
4880 return;
4881 }
4882
4883 for (int i = 0; i < current_class->variables.size(); i++) {
4884 if (current_class->variables[i].identifier == member.identifier) {
4885 _set_error("Variable \"" + String(member.identifier) + "\" already exists in this class (at line: " +
4886 itos(current_class->variables[i].line) + ").");
4887 return;
4888 }
4889 }
4890
4891 for (int i = 0; i < current_class->subclasses.size(); i++) {
4892 if (current_class->subclasses[i]->name == member.identifier) {
4893 _set_error("A class named \"" + String(member.identifier) + "\" already exists in this class (at line " + itos(current_class->subclasses[i]->line) + ").");
4894 return;
4895 }
4896 }
4897 #ifdef DEBUG_ENABLED
4898 for (int i = 0; i < current_class->functions.size(); i++) {
4899 if (current_class->functions[i]->name == member.identifier) {
4900 _add_warning(GDScriptWarning::VARIABLE_CONFLICTS_FUNCTION, member.line, member.identifier);
4901 break;
4902 }
4903 }
4904 for (int i = 0; i < current_class->static_functions.size(); i++) {
4905 if (current_class->static_functions[i]->name == member.identifier) {
4906 _add_warning(GDScriptWarning::VARIABLE_CONFLICTS_FUNCTION, member.line, member.identifier);
4907 break;
4908 }
4909 }
4910 #endif // DEBUG_ENABLED
4911 tokenizer->advance();
4912
4913 rpc_mode = MultiplayerAPI::RPC_MODE_DISABLED;
4914
4915 if (tokenizer->get_token() == GDScriptTokenizer::TK_COLON) {
4916 if (tokenizer->get_token(1) == GDScriptTokenizer::TK_OP_ASSIGN) {
4917 member.data_type = DataType();
4918 #ifdef DEBUG_ENABLED
4919 member.data_type.infer_type = true;
4920 #endif
4921 tokenizer->advance();
4922 } else if (!_parse_type(member.data_type)) {
4923 _set_error("Expected a type for the class variable.");
4924 return;
4925 }
4926 }
4927
4928 if (autoexport && member.data_type.has_type) {
4929 if (member.data_type.kind == DataType::BUILTIN) {
4930 member._export.type = member.data_type.builtin_type;
4931 } else if (member.data_type.kind == DataType::NATIVE) {
4932 if (ClassDB::is_parent_class(member.data_type.native_type, "Resource")) {
4933 member._export.type = Variant::OBJECT;
4934 member._export.hint = PROPERTY_HINT_RESOURCE_TYPE;
4935 member._export.usage |= PROPERTY_USAGE_SCRIPT_VARIABLE;
4936 member._export.hint_string = member.data_type.native_type;
4937 member._export.class_name = member.data_type.native_type;
4938 } else {
4939 _set_error("Invalid export type. Only built-in and native resource types can be exported.", member.line);
4940 return;
4941 }
4942
4943 } else {
4944 _set_error("Invalid export type. Only built-in and native resource types can be exported.", member.line);
4945 return;
4946 }
4947 }
4948
4949 #ifdef TOOLS_ENABLED
4950 Variant::CallError ce;
4951 member.default_value = Variant::construct(member._export.type, NULL, 0, ce);
4952 #endif
4953
4954 if (tokenizer->get_token() == GDScriptTokenizer::TK_OP_ASSIGN) {
4955
4956 #ifdef DEBUG_ENABLED
4957 int line = tokenizer->get_token_line();
4958 #endif
4959 tokenizer->advance();
4960
4961 Node *subexpr = _parse_and_reduce_expression(p_class, false, autoexport || member._export.type != Variant::NIL);
4962 if (!subexpr) {
4963 if (_recover_from_completion()) {
4964 break;
4965 }
4966 return;
4967 }
4968
4969 //discourage common error
4970 if (!onready && subexpr->type == Node::TYPE_OPERATOR) {
4971
4972 OperatorNode *op = static_cast<OperatorNode *>(subexpr);
4973 if (op->op == OperatorNode::OP_CALL && op->arguments[0]->type == Node::TYPE_SELF && op->arguments[1]->type == Node::TYPE_IDENTIFIER) {
4974 IdentifierNode *id = static_cast<IdentifierNode *>(op->arguments[1]);
4975 if (id->name == "get_node") {
4976
4977 _set_error("Use \"onready var " + String(member.identifier) + " = get_node(...)\" instead.");
4978 return;
4979 }
4980 }
4981 }
4982
4983 member.expression = subexpr;
4984
4985 if (autoexport && !member.data_type.has_type) {
4986
4987 if (subexpr->type != Node::TYPE_CONSTANT) {
4988
4989 _set_error("Type-less export needs a constant expression assigned to infer type.");
4990 return;
4991 }
4992
4993 ConstantNode *cn = static_cast<ConstantNode *>(subexpr);
4994 if (cn->value.get_type() == Variant::NIL) {
4995
4996 _set_error("Can't accept a null constant expression for inferring export type.");
4997 return;
4998 }
4999
5000 if (!_reduce_export_var_type(cn->value, member.line)) return;
5001
5002 member._export.type = cn->value.get_type();
5003 member._export.usage |= PROPERTY_USAGE_SCRIPT_VARIABLE;
5004 if (cn->value.get_type() == Variant::OBJECT) {
5005 Object *obj = cn->value;
5006 Resource *res = Object::cast_to<Resource>(obj);
5007 if (res == NULL) {
5008 _set_error("The exported constant isn't a type or resource.");
5009 return;
5010 }
5011 member._export.hint = PROPERTY_HINT_RESOURCE_TYPE;
5012 member._export.hint_string = res->get_class();
5013 }
5014 }
5015 #ifdef TOOLS_ENABLED
5016 if (subexpr->type == Node::TYPE_CONSTANT && (member._export.type != Variant::NIL || member.data_type.has_type)) {
5017
5018 ConstantNode *cn = static_cast<ConstantNode *>(subexpr);
5019 if (cn->value.get_type() != Variant::NIL) {
5020 if (member._export.type != Variant::NIL && cn->value.get_type() != member._export.type) {
5021 if (Variant::can_convert(cn->value.get_type(), member._export.type)) {
5022 Variant::CallError err;
5023 const Variant *args = &cn->value;
5024 cn->value = Variant::construct(member._export.type, &args, 1, err);
5025 } else {
5026 _set_error("Can't convert the provided value to the export type.");
5027 return;
5028 }
5029 }
5030 member.default_value = cn->value;
5031 }
5032 }
5033 #endif
5034
5035 IdentifierNode *id = alloc_node<IdentifierNode>();
5036 id->name = member.identifier;
5037 id->datatype = member.data_type;
5038
5039 OperatorNode *op = alloc_node<OperatorNode>();
5040 op->op = OperatorNode::OP_INIT_ASSIGN;
5041 op->arguments.push_back(id);
5042 op->arguments.push_back(subexpr);
5043
5044 #ifdef DEBUG_ENABLED
5045 NewLineNode *nl2 = alloc_node<NewLineNode>();
5046 nl2->line = line;
5047 if (onready)
5048 p_class->ready->statements.push_back(nl2);
5049 else
5050 p_class->initializer->statements.push_back(nl2);
5051 #endif
5052 if (onready)
5053 p_class->ready->statements.push_back(op);
5054 else
5055 p_class->initializer->statements.push_back(op);
5056
5057 member.initial_assignment = op;
5058
5059 } else {
5060
5061 if (autoexport && !member.data_type.has_type) {
5062 _set_error("Type-less export needs a constant expression assigned to infer type.");
5063 return;
5064 }
5065
5066 Node *expr;
5067
5068 if (member.data_type.has_type) {
5069 expr = _get_default_value_for_type(member.data_type);
5070 } else {
5071 DataType exported_type;
5072 exported_type.has_type = true;
5073 exported_type.kind = DataType::BUILTIN;
5074 exported_type.builtin_type = member._export.type;
5075 expr = _get_default_value_for_type(exported_type);
5076 }
5077
5078 IdentifierNode *id = alloc_node<IdentifierNode>();
5079 id->name = member.identifier;
5080 id->datatype = member.data_type;
5081
5082 OperatorNode *op = alloc_node<OperatorNode>();
5083 op->op = OperatorNode::OP_INIT_ASSIGN;
5084 op->arguments.push_back(id);
5085 op->arguments.push_back(expr);
5086
5087 p_class->initializer->statements.push_back(op);
5088
5089 member.initial_assignment = op;
5090 }
5091
5092 if (tokenizer->get_token() == GDScriptTokenizer::TK_PR_SETGET) {
5093
5094 tokenizer->advance();
5095
5096 if (tokenizer->get_token() != GDScriptTokenizer::TK_COMMA) {
5097 //just comma means using only getter
5098 if (!tokenizer->is_token_literal()) {
5099 _set_error("Expected an identifier for the setter function after \"setget\".");
5100 }
5101
5102 member.setter = tokenizer->get_token_literal();
5103
5104 tokenizer->advance();
5105 }
5106
5107 if (tokenizer->get_token() == GDScriptTokenizer::TK_COMMA) {
5108 //there is a getter
5109 tokenizer->advance();
5110
5111 if (!tokenizer->is_token_literal()) {
5112 _set_error("Expected an identifier for the getter function after \",\".");
5113 }
5114
5115 member.getter = tokenizer->get_token_literal();
5116 tokenizer->advance();
5117 }
5118 }
5119
5120 p_class->variables.push_back(member);
5121
5122 if (!_end_statement()) {
5123 _set_end_statement_error("var");
5124 return;
5125 }
5126 } break;
5127 case GDScriptTokenizer::TK_PR_CONST: {
5128 // constant declaration and initialization
5129
5130 ClassNode::Constant constant;
5131
5132 tokenizer->advance();
5133 if (!tokenizer->is_token_literal(0, true)) {
5134
5135 _set_error("Expected an identifier for the constant.");
5136 return;
5137 }
5138
5139 StringName const_id = tokenizer->get_token_literal();
5140 int line = tokenizer->get_token_line();
5141
5142 if (current_class->constant_expressions.has(const_id)) {
5143 _set_error("Constant \"" + String(const_id) + "\" already exists in this class (at line " +
5144 itos(current_class->constant_expressions[const_id].expression->line) + ").");
5145 return;
5146 }
5147
5148 for (int i = 0; i < current_class->variables.size(); i++) {
5149 if (current_class->variables[i].identifier == const_id) {
5150 _set_error("A variable named \"" + String(const_id) + "\" already exists in this class (at line " +
5151 itos(current_class->variables[i].line) + ").");
5152 return;
5153 }
5154 }
5155
5156 for (int i = 0; i < current_class->subclasses.size(); i++) {
5157 if (current_class->subclasses[i]->name == const_id) {
5158 _set_error("A class named \"" + String(const_id) + "\" already exists in this class (at line " + itos(current_class->subclasses[i]->line) + ").");
5159 return;
5160 }
5161 }
5162
5163 tokenizer->advance();
5164
5165 if (tokenizer->get_token() == GDScriptTokenizer::TK_COLON) {
5166 if (tokenizer->get_token(1) == GDScriptTokenizer::TK_OP_ASSIGN) {
5167 constant.type = DataType();
5168 #ifdef DEBUG_ENABLED
5169 constant.type.infer_type = true;
5170 #endif
5171 tokenizer->advance();
5172 } else if (!_parse_type(constant.type)) {
5173 _set_error("Expected a type for the class constant.");
5174 return;
5175 }
5176 }
5177
5178 if (tokenizer->get_token() != GDScriptTokenizer::TK_OP_ASSIGN) {
5179 _set_error("Constants must be assigned immediately.");
5180 return;
5181 }
5182
5183 tokenizer->advance();
5184
5185 Node *subexpr = _parse_and_reduce_expression(p_class, true, true);
5186 if (!subexpr) {
5187 if (_recover_from_completion()) {
5188 break;
5189 }
5190 return;
5191 }
5192
5193 if (subexpr->type != Node::TYPE_CONSTANT) {
5194 _set_error("Expected a constant expression.", line);
5195 return;
5196 }
5197 subexpr->line = line;
5198 constant.expression = subexpr;
5199
5200 p_class->constant_expressions.insert(const_id, constant);
5201
5202 if (!_end_statement()) {
5203 _set_end_statement_error("const");
5204 return;
5205 }
5206
5207 } break;
5208 case GDScriptTokenizer::TK_PR_ENUM: {
5209 //multiple constant declarations..
5210
5211 int last_assign = -1; // Incremented by 1 right before the assignment.
5212 String enum_name;
5213 Dictionary enum_dict;
5214 int enum_start_line = tokenizer->get_token_line();
5215
5216 tokenizer->advance();
5217 if (tokenizer->is_token_literal(0, true)) {
5218 enum_name = tokenizer->get_token_literal();
5219
5220 if (current_class->constant_expressions.has(enum_name)) {
5221 _set_error("A constant named \"" + String(enum_name) + "\" already exists in this class (at line " +
5222 itos(current_class->constant_expressions[enum_name].expression->line) + ").");
5223 return;
5224 }
5225
5226 for (int i = 0; i < current_class->variables.size(); i++) {
5227 if (current_class->variables[i].identifier == enum_name) {
5228 _set_error("A variable named \"" + String(enum_name) + "\" already exists in this class (at line " +
5229 itos(current_class->variables[i].line) + ").");
5230 return;
5231 }
5232 }
5233
5234 for (int i = 0; i < current_class->subclasses.size(); i++) {
5235 if (current_class->subclasses[i]->name == enum_name) {
5236 _set_error("A class named \"" + String(enum_name) + "\" already exists in this class (at line " + itos(current_class->subclasses[i]->line) + ").");
5237 return;
5238 }
5239 }
5240
5241 tokenizer->advance();
5242 }
5243 if (tokenizer->get_token() != GDScriptTokenizer::TK_CURLY_BRACKET_OPEN) {
5244 _set_error("Expected \"{\" in the enum declaration.");
5245 return;
5246 }
5247 tokenizer->advance();
5248
5249 while (true) {
5250 if (tokenizer->get_token() == GDScriptTokenizer::TK_NEWLINE) {
5251
5252 tokenizer->advance(); // Ignore newlines
5253 } else if (tokenizer->get_token() == GDScriptTokenizer::TK_CURLY_BRACKET_CLOSE) {
5254
5255 tokenizer->advance();
5256 break; // End of enum
5257 } else if (!tokenizer->is_token_literal(0, true)) {
5258
5259 if (tokenizer->get_token() == GDScriptTokenizer::TK_EOF) {
5260 _set_error("Unexpected end of file.");
5261 } else {
5262 _set_error(String("Unexpected ") + GDScriptTokenizer::get_token_name(tokenizer->get_token()) + ", expected an identifier.");
5263 }
5264
5265 return;
5266 } else { // tokenizer->is_token_literal(0, true)
5267 StringName const_id = tokenizer->get_token_literal();
5268
5269 tokenizer->advance();
5270
5271 ConstantNode *enum_value_expr;
5272
5273 if (tokenizer->get_token() == GDScriptTokenizer::TK_OP_ASSIGN) {
5274 tokenizer->advance();
5275
5276 Node *subexpr = _parse_and_reduce_expression(p_class, true, true);
5277 if (!subexpr) {
5278 if (_recover_from_completion()) {
5279 break;
5280 }
5281 return;
5282 }
5283
5284 if (subexpr->type != Node::TYPE_CONSTANT) {
5285 _set_error("Expected a constant expression.");
5286 return;
5287 }
5288
5289 enum_value_expr = static_cast<ConstantNode *>(subexpr);
5290
5291 if (enum_value_expr->value.get_type() != Variant::INT) {
5292 _set_error("Expected an integer value for \"enum\".");
5293 return;
5294 }
5295
5296 last_assign = enum_value_expr->value;
5297
5298 } else {
5299 last_assign = last_assign + 1;
5300 enum_value_expr = alloc_node<ConstantNode>();
5301 enum_value_expr->value = last_assign;
5302 enum_value_expr->datatype = _type_from_variant(enum_value_expr->value);
5303 }
5304
5305 if (tokenizer->get_token() == GDScriptTokenizer::TK_COMMA) {
5306 tokenizer->advance();
5307 } else if (tokenizer->is_token_literal(0, true)) {
5308 _set_error("Unexpected identifier.");
5309 return;
5310 }
5311
5312 if (enum_name != "") {
5313 enum_dict[const_id] = enum_value_expr->value;
5314 } else {
5315 if (current_class->constant_expressions.has(const_id)) {
5316 _set_error("A constant named \"" + String(const_id) + "\" already exists in this class (at line " +
5317 itos(current_class->constant_expressions[const_id].expression->line) + ").");
5318 return;
5319 }
5320
5321 for (int i = 0; i < current_class->variables.size(); i++) {
5322 if (current_class->variables[i].identifier == const_id) {
5323 _set_error("A variable named \"" + String(const_id) + "\" already exists in this class (at line " +
5324 itos(current_class->variables[i].line) + ").");
5325 return;
5326 }
5327 }
5328
5329 for (int i = 0; i < current_class->subclasses.size(); i++) {
5330 if (current_class->subclasses[i]->name == const_id) {
5331 _set_error("A class named \"" + String(const_id) + "\" already exists in this class (at line " + itos(current_class->subclasses[i]->line) + ").");
5332 return;
5333 }
5334 }
5335
5336 ClassNode::Constant constant;
5337 constant.type.has_type = true;
5338 constant.type.kind = DataType::BUILTIN;
5339 constant.type.builtin_type = Variant::INT;
5340 constant.expression = enum_value_expr;
5341 p_class->constant_expressions.insert(const_id, constant);
5342 }
5343 }
5344 }
5345
5346 if (enum_name != "") {
5347 ClassNode::Constant enum_constant;
5348 ConstantNode *cn = alloc_node<ConstantNode>();
5349 cn->value = enum_dict;
5350 cn->datatype = _type_from_variant(cn->value);
5351 cn->line = enum_start_line;
5352
5353 enum_constant.expression = cn;
5354 enum_constant.type = cn->datatype;
5355 p_class->constant_expressions.insert(enum_name, enum_constant);
5356 }
5357
5358 if (!_end_statement()) {
5359 _set_end_statement_error("enum");
5360 return;
5361 }
5362
5363 } break;
5364
5365 case GDScriptTokenizer::TK_CONSTANT: {
5366 if (tokenizer->get_token_constant().get_type() == Variant::STRING) {
5367 tokenizer->advance();
5368 // Ignore
5369 } else {
5370 _set_error(String() + "Unexpected constant of type: " + Variant::get_type_name(tokenizer->get_token_constant().get_type()));
5371 return;
5372 }
5373 } break;
5374
5375 case GDScriptTokenizer::TK_CF_PASS: {
5376 tokenizer->advance();
5377 } break;
5378
5379 default: {
5380
5381 if (token == GDScriptTokenizer::TK_IDENTIFIER) {
5382 completion_type = COMPLETION_IDENTIFIER;
5383 completion_class = current_class;
5384 completion_function = current_function;
5385 completion_line = tokenizer->get_token_line();
5386 completion_block = current_block;
5387 completion_ident_is_call = false;
5388 completion_found = true;
5389 }
5390
5391 _set_error(String() + "Unexpected token: " + tokenizer->get_token_name(tokenizer->get_token()) + ":" + tokenizer->get_token_identifier());
5392 return;
5393
5394 } break;
5395 }
5396 }
5397 }
5398
_determine_inheritance(ClassNode * p_class,bool p_recursive)5399 void GDScriptParser::_determine_inheritance(ClassNode *p_class, bool p_recursive) {
5400
5401 if (p_class->base_type.has_type) {
5402 // Already determined
5403 } else if (p_class->extends_used) {
5404 //do inheritance
5405 String path = p_class->extends_file;
5406
5407 Ref<GDScript> script;
5408 StringName native;
5409 ClassNode *base_class = NULL;
5410
5411 if (path != "") {
5412 //path (and optionally subclasses)
5413
5414 if (path.is_rel_path()) {
5415
5416 String base = base_path;
5417
5418 if (base == "" || base.is_rel_path()) {
5419 _set_error("Couldn't resolve relative path for the parent class: " + path, p_class->line);
5420 return;
5421 }
5422 path = base.plus_file(path).simplify_path();
5423 }
5424 script = ResourceLoader::load(path);
5425 if (script.is_null()) {
5426 _set_error("Couldn't load the base class: " + path, p_class->line);
5427 return;
5428 }
5429 if (!script->is_valid()) {
5430
5431 _set_error("Script isn't fully loaded (cyclic preload?): " + path, p_class->line);
5432 return;
5433 }
5434
5435 if (p_class->extends_class.size()) {
5436
5437 for (int i = 0; i < p_class->extends_class.size(); i++) {
5438
5439 String sub = p_class->extends_class[i];
5440 if (script->get_subclasses().has(sub)) {
5441
5442 Ref<Script> subclass = script->get_subclasses()[sub]; //avoid reference from disappearing
5443 script = subclass;
5444 } else {
5445
5446 _set_error("Couldn't find the subclass: " + sub, p_class->line);
5447 return;
5448 }
5449 }
5450 }
5451
5452 } else {
5453
5454 if (p_class->extends_class.size() == 0) {
5455 _set_error("Parser bug: undecidable inheritance.", p_class->line);
5456 ERR_FAIL();
5457 }
5458 //look around for the subclasses
5459
5460 int extend_iter = 1;
5461 String base = p_class->extends_class[0];
5462 ClassNode *p = p_class->owner;
5463 Ref<GDScript> base_script;
5464
5465 if (ScriptServer::is_global_class(base)) {
5466 base_script = ResourceLoader::load(ScriptServer::get_global_class_path(base));
5467 if (!base_script.is_valid()) {
5468 _set_error("The class \"" + base + "\" couldn't be fully loaded (script error or cyclic dependency).", p_class->line);
5469 return;
5470 }
5471 p = NULL;
5472 } else {
5473 List<PropertyInfo> props;
5474 ProjectSettings::get_singleton()->get_property_list(&props);
5475 for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) {
5476 String s = E->get().name;
5477 if (!s.begins_with("autoload/")) {
5478 continue;
5479 }
5480 String name = s.get_slice("/", 1);
5481 if (name == base) {
5482 String singleton_path = ProjectSettings::get_singleton()->get(s);
5483 if (singleton_path.begins_with("*")) {
5484 singleton_path = singleton_path.right(1);
5485 }
5486 if (!singleton_path.begins_with("res://")) {
5487 singleton_path = "res://" + singleton_path;
5488 }
5489 base_script = ResourceLoader::load(singleton_path);
5490 if (!base_script.is_valid()) {
5491 _set_error("Class '" + base + "' could not be fully loaded (script error or cyclic inheritance).", p_class->line);
5492 return;
5493 }
5494 p = NULL;
5495 }
5496 }
5497 }
5498
5499 while (p) {
5500
5501 bool found = false;
5502
5503 for (int i = 0; i < p->subclasses.size(); i++) {
5504 if (p->subclasses[i]->name == base) {
5505 ClassNode *test = p->subclasses[i];
5506 while (test) {
5507 if (test == p_class) {
5508 _set_error("Cyclic inheritance.", test->line);
5509 return;
5510 }
5511 if (test->base_type.kind == DataType::CLASS) {
5512 test = test->base_type.class_type;
5513 } else {
5514 break;
5515 }
5516 }
5517 found = true;
5518 if (extend_iter < p_class->extends_class.size()) {
5519 // Keep looking at current classes if possible
5520 base = p_class->extends_class[extend_iter++];
5521 p = p->subclasses[i];
5522 } else {
5523 base_class = p->subclasses[i];
5524 }
5525 break;
5526 }
5527 }
5528
5529 if (base_class) break;
5530 if (found) continue;
5531
5532 if (p->constant_expressions.has(base)) {
5533 if (p->constant_expressions[base].expression->type != Node::TYPE_CONSTANT) {
5534 _set_error("Couldn't resolve the constant \"" + base + "\".", p_class->line);
5535 return;
5536 }
5537 const ConstantNode *cn = static_cast<const ConstantNode *>(p->constant_expressions[base].expression);
5538 base_script = cn->value;
5539 if (base_script.is_null()) {
5540 _set_error("Constant isn't a class: " + base, p_class->line);
5541 return;
5542 }
5543 break;
5544 }
5545
5546 p = p->owner;
5547 }
5548
5549 if (base_script.is_valid()) {
5550
5551 String ident = base;
5552 Ref<GDScript> find_subclass = base_script;
5553
5554 for (int i = extend_iter; i < p_class->extends_class.size(); i++) {
5555
5556 String subclass = p_class->extends_class[i];
5557
5558 ident += ("." + subclass);
5559
5560 if (find_subclass->get_subclasses().has(subclass)) {
5561
5562 find_subclass = find_subclass->get_subclasses()[subclass];
5563 } else if (find_subclass->get_constants().has(subclass)) {
5564
5565 Ref<GDScript> new_base_class = find_subclass->get_constants()[subclass];
5566 if (new_base_class.is_null()) {
5567 _set_error("Constant isn't a class: " + ident, p_class->line);
5568 return;
5569 }
5570 find_subclass = new_base_class;
5571 } else {
5572
5573 _set_error("Couldn't find the subclass: " + ident, p_class->line);
5574 return;
5575 }
5576 }
5577
5578 script = find_subclass;
5579
5580 } else if (!base_class) {
5581
5582 if (p_class->extends_class.size() > 1) {
5583
5584 _set_error("Invalid inheritance (unknown class + subclasses).", p_class->line);
5585 return;
5586 }
5587 //if not found, try engine classes
5588 if (!GDScriptLanguage::get_singleton()->get_global_map().has(base)) {
5589
5590 _set_error("Unknown class: \"" + base + "\"", p_class->line);
5591 return;
5592 }
5593
5594 native = base;
5595 }
5596 }
5597
5598 if (base_class) {
5599 p_class->base_type.has_type = true;
5600 p_class->base_type.kind = DataType::CLASS;
5601 p_class->base_type.class_type = base_class;
5602 } else if (script.is_valid()) {
5603 p_class->base_type.has_type = true;
5604 p_class->base_type.kind = DataType::GDSCRIPT;
5605 p_class->base_type.script_type = script;
5606 p_class->base_type.native_type = script->get_instance_base_type();
5607 } else if (native != StringName()) {
5608 p_class->base_type.has_type = true;
5609 p_class->base_type.kind = DataType::NATIVE;
5610 p_class->base_type.native_type = native;
5611 } else {
5612 _set_error("Couldn't determine inheritance.", p_class->line);
5613 return;
5614 }
5615
5616 } else {
5617 // without extends, implicitly extend Reference
5618 p_class->base_type.has_type = true;
5619 p_class->base_type.kind = DataType::NATIVE;
5620 p_class->base_type.native_type = "Reference";
5621 }
5622
5623 if (p_recursive) {
5624 // Recursively determine subclasses
5625 for (int i = 0; i < p_class->subclasses.size(); i++) {
5626 _determine_inheritance(p_class->subclasses[i], p_recursive);
5627 }
5628 }
5629 }
5630
to_string() const5631 String GDScriptParser::DataType::to_string() const {
5632 if (!has_type) return "var";
5633 switch (kind) {
5634 case BUILTIN: {
5635 if (builtin_type == Variant::NIL) return "null";
5636 return Variant::get_type_name(builtin_type);
5637 } break;
5638 case NATIVE: {
5639 if (is_meta_type) {
5640 return "GDScriptNativeClass";
5641 }
5642 return native_type.operator String();
5643 } break;
5644
5645 case GDSCRIPT: {
5646 Ref<GDScript> gds = script_type;
5647 const String &gds_class = gds->get_script_class_name();
5648 if (!gds_class.empty()) {
5649 return gds_class;
5650 }
5651 FALLTHROUGH;
5652 }
5653 case SCRIPT: {
5654 if (is_meta_type) {
5655 return script_type->get_class_name().operator String();
5656 }
5657 String name = script_type->get_name();
5658 if (name != String()) {
5659 return name;
5660 }
5661 name = script_type->get_path().get_file();
5662 if (name != String()) {
5663 return name;
5664 }
5665 return native_type.operator String();
5666 } break;
5667 case CLASS: {
5668 ERR_FAIL_COND_V(!class_type, String());
5669 if (is_meta_type) {
5670 return "GDScript";
5671 }
5672 if (class_type->name == StringName()) {
5673 return "self";
5674 }
5675 return class_type->name.operator String();
5676 } break;
5677 case UNRESOLVED: {
5678 } break;
5679 }
5680
5681 return "Unresolved";
5682 }
5683
_parse_type(DataType & r_type,bool p_can_be_void)5684 bool GDScriptParser::_parse_type(DataType &r_type, bool p_can_be_void) {
5685 tokenizer->advance();
5686 r_type.has_type = true;
5687
5688 bool finished = false;
5689 bool can_index = false;
5690 String full_name;
5691
5692 if (tokenizer->get_token() == GDScriptTokenizer::TK_CURSOR) {
5693 completion_cursor = StringName();
5694 completion_type = COMPLETION_TYPE_HINT;
5695 completion_class = current_class;
5696 completion_function = current_function;
5697 completion_line = tokenizer->get_token_line();
5698 completion_argument = 0;
5699 completion_block = current_block;
5700 completion_found = true;
5701 completion_ident_is_call = p_can_be_void;
5702 tokenizer->advance();
5703 }
5704
5705 switch (tokenizer->get_token()) {
5706 case GDScriptTokenizer::TK_PR_VOID: {
5707 if (!p_can_be_void) {
5708 return false;
5709 }
5710 r_type.kind = DataType::BUILTIN;
5711 r_type.builtin_type = Variant::NIL;
5712 } break;
5713 case GDScriptTokenizer::TK_BUILT_IN_TYPE: {
5714 r_type.builtin_type = tokenizer->get_token_type();
5715 if (tokenizer->get_token_type() == Variant::OBJECT) {
5716 r_type.kind = DataType::NATIVE;
5717 r_type.native_type = "Object";
5718 } else {
5719 r_type.kind = DataType::BUILTIN;
5720 }
5721 } break;
5722 case GDScriptTokenizer::TK_IDENTIFIER: {
5723 r_type.native_type = tokenizer->get_token_identifier();
5724 if (ClassDB::class_exists(r_type.native_type) || ClassDB::class_exists("_" + r_type.native_type.operator String())) {
5725 r_type.kind = DataType::NATIVE;
5726 } else {
5727 r_type.kind = DataType::UNRESOLVED;
5728 can_index = true;
5729 full_name = r_type.native_type;
5730 }
5731 } break;
5732 default: {
5733 return false;
5734 }
5735 }
5736
5737 tokenizer->advance();
5738
5739 if (tokenizer->get_token() == GDScriptTokenizer::TK_CURSOR) {
5740 completion_cursor = r_type.native_type;
5741 completion_type = COMPLETION_TYPE_HINT;
5742 completion_class = current_class;
5743 completion_function = current_function;
5744 completion_line = tokenizer->get_token_line();
5745 completion_argument = 0;
5746 completion_block = current_block;
5747 completion_found = true;
5748 completion_ident_is_call = p_can_be_void;
5749 tokenizer->advance();
5750 }
5751
5752 if (can_index) {
5753 while (!finished) {
5754 switch (tokenizer->get_token()) {
5755 case GDScriptTokenizer::TK_PERIOD: {
5756 if (!can_index) {
5757 _set_error("Unexpected \".\".");
5758 return false;
5759 }
5760 can_index = false;
5761 tokenizer->advance();
5762 } break;
5763 case GDScriptTokenizer::TK_IDENTIFIER: {
5764 if (can_index) {
5765 _set_error("Unexpected identifier.");
5766 return false;
5767 }
5768
5769 StringName id;
5770 bool has_completion = _get_completable_identifier(COMPLETION_TYPE_HINT_INDEX, id);
5771 if (id == StringName()) {
5772 id = "@temp";
5773 }
5774
5775 full_name += "." + id.operator String();
5776 can_index = true;
5777 if (has_completion) {
5778 completion_cursor = full_name;
5779 }
5780 } break;
5781 default: {
5782 finished = true;
5783 } break;
5784 }
5785 }
5786
5787 if (tokenizer->get_token(-1) == GDScriptTokenizer::TK_PERIOD) {
5788 _set_error("Expected a subclass identifier.");
5789 return false;
5790 }
5791
5792 r_type.native_type = full_name;
5793 }
5794
5795 return true;
5796 }
5797
_resolve_type(const DataType & p_source,int p_line)5798 GDScriptParser::DataType GDScriptParser::_resolve_type(const DataType &p_source, int p_line) {
5799 if (!p_source.has_type) return p_source;
5800 if (p_source.kind != DataType::UNRESOLVED) return p_source;
5801
5802 Vector<String> full_name = p_source.native_type.operator String().split(".", false);
5803 int name_part = 0;
5804
5805 DataType result;
5806 result.has_type = true;
5807
5808 while (name_part < full_name.size()) {
5809
5810 bool found = false;
5811 StringName id = full_name[name_part];
5812 DataType base_type = result;
5813
5814 ClassNode *p = NULL;
5815 if (name_part == 0) {
5816 if (ScriptServer::is_global_class(id)) {
5817 String script_path = ScriptServer::get_global_class_path(id);
5818 if (script_path == self_path) {
5819 result.kind = DataType::CLASS;
5820 result.class_type = static_cast<ClassNode *>(head);
5821 } else {
5822 Ref<Script> script = ResourceLoader::load(script_path);
5823 Ref<GDScript> gds = script;
5824 if (gds.is_valid()) {
5825 if (!gds->is_valid()) {
5826 _set_error("The class \"" + id + "\" couldn't be fully loaded (script error or cyclic dependency).", p_line);
5827 return DataType();
5828 }
5829 result.kind = DataType::GDSCRIPT;
5830 result.script_type = gds;
5831 } else if (script.is_valid()) {
5832 result.kind = DataType::SCRIPT;
5833 result.script_type = script;
5834 } else {
5835 _set_error("The class \"" + id + "\" was found in global scope, but its script couldn't be loaded.", p_line);
5836 return DataType();
5837 }
5838 }
5839 name_part++;
5840 continue;
5841 }
5842 List<PropertyInfo> props;
5843 ProjectSettings::get_singleton()->get_property_list(&props);
5844 String singleton_path;
5845 for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) {
5846 String s = E->get().name;
5847 if (!s.begins_with("autoload/")) {
5848 continue;
5849 }
5850 String name = s.get_slice("/", 1);
5851 if (name == id) {
5852 singleton_path = ProjectSettings::get_singleton()->get(s);
5853 if (singleton_path.begins_with("*")) {
5854 singleton_path = singleton_path.right(1);
5855 }
5856 if (!singleton_path.begins_with("res://")) {
5857 singleton_path = "res://" + singleton_path;
5858 }
5859 break;
5860 }
5861 }
5862 if (!singleton_path.empty()) {
5863 Ref<Script> script = ResourceLoader::load(singleton_path);
5864 Ref<GDScript> gds = script;
5865 if (gds.is_valid()) {
5866 if (!gds->is_valid()) {
5867 _set_error("Class '" + id + "' could not be fully loaded (script error or cyclic inheritance).", p_line);
5868 return DataType();
5869 }
5870 result.kind = DataType::GDSCRIPT;
5871 result.script_type = gds;
5872 } else if (script.is_valid()) {
5873 result.kind = DataType::SCRIPT;
5874 result.script_type = script;
5875 } else {
5876 _set_error("Couldn't fully load singleton script '" + id + "' (possible cyclic reference or parse error).", p_line);
5877 return DataType();
5878 }
5879 name_part++;
5880 continue;
5881 }
5882
5883 p = current_class;
5884 } else if (base_type.kind == DataType::CLASS) {
5885 p = base_type.class_type;
5886 }
5887 while (p) {
5888 if (p->constant_expressions.has(id)) {
5889 if (p->constant_expressions[id].expression->type != Node::TYPE_CONSTANT) {
5890 _set_error("Parser bug: unresolved constant.", p_line);
5891 ERR_FAIL_V(result);
5892 }
5893 const ConstantNode *cn = static_cast<const ConstantNode *>(p->constant_expressions[id].expression);
5894 Ref<GDScript> gds = cn->value;
5895 if (gds.is_valid()) {
5896 result.kind = DataType::GDSCRIPT;
5897 result.script_type = gds;
5898 found = true;
5899 } else {
5900 Ref<Script> scr = cn->value;
5901 if (scr.is_valid()) {
5902 result.kind = DataType::SCRIPT;
5903 result.script_type = scr;
5904 found = true;
5905 }
5906 }
5907 break;
5908 }
5909
5910 // Inner classes
5911 ClassNode *outer_class = p;
5912 while (outer_class) {
5913 if (outer_class->name == id) {
5914 found = true;
5915 result.kind = DataType::CLASS;
5916 result.class_type = outer_class;
5917 break;
5918 }
5919 for (int i = 0; i < outer_class->subclasses.size(); i++) {
5920 if (outer_class->subclasses[i] == p) {
5921 continue;
5922 }
5923 if (outer_class->subclasses[i]->name == id) {
5924 found = true;
5925 result.kind = DataType::CLASS;
5926 result.class_type = outer_class->subclasses[i];
5927 break;
5928 }
5929 }
5930 if (found) {
5931 break;
5932 }
5933 outer_class = outer_class->owner;
5934 }
5935
5936 if (!found && p->base_type.kind == DataType::CLASS) {
5937 p = p->base_type.class_type;
5938 } else {
5939 base_type = p->base_type;
5940 break;
5941 }
5942 }
5943
5944 // Still look for class constants in parent scripts
5945 if (!found && (base_type.kind == DataType::GDSCRIPT || base_type.kind == DataType::SCRIPT)) {
5946 Ref<Script> scr = base_type.script_type;
5947 ERR_FAIL_COND_V(scr.is_null(), result);
5948 while (scr.is_valid()) {
5949 Map<StringName, Variant> constants;
5950 scr->get_constants(&constants);
5951
5952 if (constants.has(id)) {
5953 Ref<GDScript> gds = constants[id];
5954
5955 if (gds.is_valid()) {
5956 result.kind = DataType::GDSCRIPT;
5957 result.script_type = gds;
5958 found = true;
5959 } else {
5960 Ref<Script> scr2 = constants[id];
5961 if (scr2.is_valid()) {
5962 result.kind = DataType::SCRIPT;
5963 result.script_type = scr2;
5964 found = true;
5965 }
5966 }
5967 }
5968 if (found) {
5969 break;
5970 } else {
5971 scr = scr->get_base_script();
5972 }
5973 }
5974 }
5975
5976 if (!found && !for_completion) {
5977 String base;
5978 if (name_part == 0) {
5979 base = "self";
5980 } else {
5981 base = result.to_string();
5982 }
5983 _set_error("The identifier \"" + String(id) + "\" isn't a valid type (not a script or class), or couldn't be found on base \"" +
5984 base + "\".",
5985 p_line);
5986 return DataType();
5987 }
5988
5989 name_part++;
5990 }
5991
5992 return result;
5993 }
5994
_type_from_variant(const Variant & p_value) const5995 GDScriptParser::DataType GDScriptParser::_type_from_variant(const Variant &p_value) const {
5996 DataType result;
5997 result.has_type = true;
5998 result.is_constant = true;
5999 result.kind = DataType::BUILTIN;
6000 result.builtin_type = p_value.get_type();
6001
6002 if (result.builtin_type == Variant::OBJECT) {
6003 Object *obj = p_value.operator Object *();
6004 if (!obj) {
6005 return DataType();
6006 }
6007 result.native_type = obj->get_class_name();
6008 Ref<Script> scr = p_value;
6009 if (scr.is_valid()) {
6010 result.is_meta_type = true;
6011 } else {
6012 result.is_meta_type = false;
6013 scr = obj->get_script();
6014 }
6015 if (scr.is_valid()) {
6016 result.script_type = scr;
6017 Ref<GDScript> gds = scr;
6018 if (gds.is_valid()) {
6019 result.kind = DataType::GDSCRIPT;
6020 } else {
6021 result.kind = DataType::SCRIPT;
6022 }
6023 result.native_type = scr->get_instance_base_type();
6024 } else {
6025 result.kind = DataType::NATIVE;
6026 }
6027 }
6028
6029 return result;
6030 }
6031
_type_from_property(const PropertyInfo & p_property,bool p_nil_is_variant) const6032 GDScriptParser::DataType GDScriptParser::_type_from_property(const PropertyInfo &p_property, bool p_nil_is_variant) const {
6033 DataType ret;
6034 if (p_property.type == Variant::NIL && (p_nil_is_variant || (p_property.usage & PROPERTY_USAGE_NIL_IS_VARIANT))) {
6035 // Variant
6036 return ret;
6037 }
6038 ret.has_type = true;
6039 ret.builtin_type = p_property.type;
6040 if (p_property.type == Variant::OBJECT) {
6041 ret.kind = DataType::NATIVE;
6042 ret.native_type = p_property.class_name == StringName() ? "Object" : p_property.class_name;
6043 } else {
6044 ret.kind = DataType::BUILTIN;
6045 }
6046 return ret;
6047 }
6048
_type_from_gdtype(const GDScriptDataType & p_gdtype) const6049 GDScriptParser::DataType GDScriptParser::_type_from_gdtype(const GDScriptDataType &p_gdtype) const {
6050 DataType result;
6051 if (!p_gdtype.has_type) {
6052 return result;
6053 }
6054
6055 result.has_type = true;
6056 result.builtin_type = p_gdtype.builtin_type;
6057 result.native_type = p_gdtype.native_type;
6058 result.script_type = p_gdtype.script_type;
6059
6060 switch (p_gdtype.kind) {
6061 case GDScriptDataType::UNINITIALIZED: {
6062 ERR_PRINT("Uninitialized datatype. Please report a bug.");
6063 } break;
6064 case GDScriptDataType::BUILTIN: {
6065 result.kind = DataType::BUILTIN;
6066 } break;
6067 case GDScriptDataType::NATIVE: {
6068 result.kind = DataType::NATIVE;
6069 } break;
6070 case GDScriptDataType::GDSCRIPT: {
6071 result.kind = DataType::GDSCRIPT;
6072 } break;
6073 case GDScriptDataType::SCRIPT: {
6074 result.kind = DataType::SCRIPT;
6075 } break;
6076 }
6077 return result;
6078 }
6079
_get_operation_type(const Variant::Operator p_op,const DataType & p_a,const DataType & p_b,bool & r_valid) const6080 GDScriptParser::DataType GDScriptParser::_get_operation_type(const Variant::Operator p_op, const DataType &p_a, const DataType &p_b, bool &r_valid) const {
6081 if (!p_a.has_type || !p_b.has_type) {
6082 r_valid = true;
6083 return DataType();
6084 }
6085
6086 Variant::Type a_type = p_a.kind == DataType::BUILTIN ? p_a.builtin_type : Variant::OBJECT;
6087 Variant::Type b_type = p_b.kind == DataType::BUILTIN ? p_b.builtin_type : Variant::OBJECT;
6088
6089 Variant a;
6090 REF a_ref;
6091 if (a_type == Variant::OBJECT) {
6092 a_ref.instance();
6093 a = a_ref;
6094 } else {
6095 Variant::CallError err;
6096 a = Variant::construct(a_type, NULL, 0, err);
6097 if (err.error != Variant::CallError::CALL_OK) {
6098 r_valid = false;
6099 return DataType();
6100 }
6101 }
6102 Variant b;
6103 REF b_ref;
6104 if (b_type == Variant::OBJECT) {
6105 b_ref.instance();
6106 b = b_ref;
6107 } else {
6108 Variant::CallError err;
6109 b = Variant::construct(b_type, NULL, 0, err);
6110 if (err.error != Variant::CallError::CALL_OK) {
6111 r_valid = false;
6112 return DataType();
6113 }
6114 }
6115
6116 // Avoid division by zero
6117 if (a_type == Variant::INT || a_type == Variant::REAL) {
6118 Variant::evaluate(Variant::OP_ADD, a, 1, a, r_valid);
6119 }
6120 if (b_type == Variant::INT || b_type == Variant::REAL) {
6121 Variant::evaluate(Variant::OP_ADD, b, 1, b, r_valid);
6122 }
6123 if (a_type == Variant::STRING && b_type != Variant::ARRAY) {
6124 a = "%s"; // Work around for formatting operator (%)
6125 }
6126
6127 Variant ret;
6128 Variant::evaluate(p_op, a, b, ret, r_valid);
6129
6130 if (r_valid) {
6131 return _type_from_variant(ret);
6132 }
6133
6134 return DataType();
6135 }
6136
_get_variant_operation(const OperatorNode::Operator & p_op) const6137 Variant::Operator GDScriptParser::_get_variant_operation(const OperatorNode::Operator &p_op) const {
6138 switch (p_op) {
6139 case OperatorNode::OP_NEG: {
6140 return Variant::OP_NEGATE;
6141 } break;
6142 case OperatorNode::OP_POS: {
6143 return Variant::OP_POSITIVE;
6144 } break;
6145 case OperatorNode::OP_NOT: {
6146 return Variant::OP_NOT;
6147 } break;
6148 case OperatorNode::OP_BIT_INVERT: {
6149 return Variant::OP_BIT_NEGATE;
6150 } break;
6151 case OperatorNode::OP_IN: {
6152 return Variant::OP_IN;
6153 } break;
6154 case OperatorNode::OP_EQUAL: {
6155 return Variant::OP_EQUAL;
6156 } break;
6157 case OperatorNode::OP_NOT_EQUAL: {
6158 return Variant::OP_NOT_EQUAL;
6159 } break;
6160 case OperatorNode::OP_LESS: {
6161 return Variant::OP_LESS;
6162 } break;
6163 case OperatorNode::OP_LESS_EQUAL: {
6164 return Variant::OP_LESS_EQUAL;
6165 } break;
6166 case OperatorNode::OP_GREATER: {
6167 return Variant::OP_GREATER;
6168 } break;
6169 case OperatorNode::OP_GREATER_EQUAL: {
6170 return Variant::OP_GREATER_EQUAL;
6171 } break;
6172 case OperatorNode::OP_AND: {
6173 return Variant::OP_AND;
6174 } break;
6175 case OperatorNode::OP_OR: {
6176 return Variant::OP_OR;
6177 } break;
6178 case OperatorNode::OP_ASSIGN_ADD:
6179 case OperatorNode::OP_ADD: {
6180 return Variant::OP_ADD;
6181 } break;
6182 case OperatorNode::OP_ASSIGN_SUB:
6183 case OperatorNode::OP_SUB: {
6184 return Variant::OP_SUBTRACT;
6185 } break;
6186 case OperatorNode::OP_ASSIGN_MUL:
6187 case OperatorNode::OP_MUL: {
6188 return Variant::OP_MULTIPLY;
6189 } break;
6190 case OperatorNode::OP_ASSIGN_DIV:
6191 case OperatorNode::OP_DIV: {
6192 return Variant::OP_DIVIDE;
6193 } break;
6194 case OperatorNode::OP_ASSIGN_MOD:
6195 case OperatorNode::OP_MOD: {
6196 return Variant::OP_MODULE;
6197 } break;
6198 case OperatorNode::OP_ASSIGN_BIT_AND:
6199 case OperatorNode::OP_BIT_AND: {
6200 return Variant::OP_BIT_AND;
6201 } break;
6202 case OperatorNode::OP_ASSIGN_BIT_OR:
6203 case OperatorNode::OP_BIT_OR: {
6204 return Variant::OP_BIT_OR;
6205 } break;
6206 case OperatorNode::OP_ASSIGN_BIT_XOR:
6207 case OperatorNode::OP_BIT_XOR: {
6208 return Variant::OP_BIT_XOR;
6209 } break;
6210 case OperatorNode::OP_ASSIGN_SHIFT_LEFT:
6211 case OperatorNode::OP_SHIFT_LEFT: {
6212 return Variant::OP_SHIFT_LEFT;
6213 }
6214 case OperatorNode::OP_ASSIGN_SHIFT_RIGHT:
6215 case OperatorNode::OP_SHIFT_RIGHT: {
6216 return Variant::OP_SHIFT_RIGHT;
6217 }
6218 default: {
6219 return Variant::OP_MAX;
6220 } break;
6221 }
6222 }
6223
_is_type_compatible(const DataType & p_container,const DataType & p_expression,bool p_allow_implicit_conversion) const6224 bool GDScriptParser::_is_type_compatible(const DataType &p_container, const DataType &p_expression, bool p_allow_implicit_conversion) const {
6225 // Ignore for completion
6226 if (!check_types || for_completion) {
6227 return true;
6228 }
6229 // Can't test if not all have type
6230 if (!p_container.has_type || !p_expression.has_type) {
6231 return true;
6232 }
6233
6234 // Should never get here unresolved
6235 ERR_FAIL_COND_V(p_container.kind == DataType::UNRESOLVED, false);
6236 ERR_FAIL_COND_V(p_expression.kind == DataType::UNRESOLVED, false);
6237
6238 if (p_container.kind == DataType::BUILTIN && p_expression.kind == DataType::BUILTIN) {
6239 bool valid = p_container.builtin_type == p_expression.builtin_type;
6240 if (p_allow_implicit_conversion) {
6241 valid = valid || Variant::can_convert_strict(p_expression.builtin_type, p_container.builtin_type);
6242 }
6243 return valid;
6244 }
6245
6246 if (p_container.kind == DataType::BUILTIN && p_container.builtin_type == Variant::OBJECT) {
6247 // Object built-in is a special case, it's compatible with any object and with null
6248 if (p_expression.kind == DataType::BUILTIN) {
6249 return p_expression.builtin_type == Variant::NIL;
6250 }
6251 // If it's not a built-in, must be an object
6252 return true;
6253 }
6254
6255 if (p_container.kind == DataType::BUILTIN || (p_expression.kind == DataType::BUILTIN && p_expression.builtin_type != Variant::NIL)) {
6256 // Can't mix built-ins with objects
6257 return false;
6258 }
6259
6260 // From now on everything is objects, check polymorphism
6261 // The container must be the same class or a superclass of the expression
6262
6263 if (p_expression.kind == DataType::BUILTIN && p_expression.builtin_type == Variant::NIL) {
6264 // Null can be assigned to object types
6265 return true;
6266 }
6267
6268 StringName expr_native;
6269 Ref<Script> expr_script;
6270 ClassNode *expr_class = NULL;
6271
6272 switch (p_expression.kind) {
6273 case DataType::NATIVE: {
6274 if (p_container.kind != DataType::NATIVE) {
6275 // Non-native type can't be a superclass of a native type
6276 return false;
6277 }
6278 if (p_expression.is_meta_type) {
6279 expr_native = GDScriptNativeClass::get_class_static();
6280 } else {
6281 expr_native = p_expression.native_type;
6282 }
6283 } break;
6284 case DataType::SCRIPT:
6285 case DataType::GDSCRIPT: {
6286 if (p_container.kind == DataType::CLASS) {
6287 // This cannot be resolved without cyclic dependencies, so just bail out
6288 return false;
6289 }
6290 if (p_expression.is_meta_type) {
6291 expr_native = p_expression.script_type->get_class_name();
6292 } else {
6293 expr_script = p_expression.script_type;
6294 expr_native = expr_script->get_instance_base_type();
6295 }
6296 } break;
6297 case DataType::CLASS: {
6298 if (p_expression.is_meta_type) {
6299 expr_native = GDScript::get_class_static();
6300 } else {
6301 expr_class = p_expression.class_type;
6302 ClassNode *base = expr_class;
6303 while (base->base_type.kind == DataType::CLASS) {
6304 base = base->base_type.class_type;
6305 }
6306 expr_native = base->base_type.native_type;
6307 expr_script = base->base_type.script_type;
6308 }
6309 } break;
6310 case DataType::BUILTIN: // Already handled above
6311 case DataType::UNRESOLVED: // Not allowed, see above
6312 break;
6313 }
6314
6315 // Some classes are prefixed with `_` internally
6316 if (!ClassDB::class_exists(expr_native)) {
6317 expr_native = "_" + expr_native;
6318 }
6319
6320 switch (p_container.kind) {
6321 case DataType::NATIVE: {
6322 if (p_container.is_meta_type) {
6323 return ClassDB::is_parent_class(expr_native, GDScriptNativeClass::get_class_static());
6324 } else {
6325 StringName container_native = ClassDB::class_exists(p_container.native_type) ? p_container.native_type : StringName("_" + p_container.native_type);
6326 return ClassDB::is_parent_class(expr_native, container_native);
6327 }
6328 } break;
6329 case DataType::SCRIPT:
6330 case DataType::GDSCRIPT: {
6331 if (p_container.is_meta_type) {
6332 return ClassDB::is_parent_class(expr_native, GDScript::get_class_static());
6333 }
6334 if (expr_class == head && p_container.script_type->get_path() == self_path) {
6335 // Special case: container is self script and expression is self
6336 return true;
6337 }
6338 while (expr_script.is_valid()) {
6339 if (expr_script == p_container.script_type) {
6340 return true;
6341 }
6342 expr_script = expr_script->get_base_script();
6343 }
6344 return false;
6345 } break;
6346 case DataType::CLASS: {
6347 if (p_container.is_meta_type) {
6348 return ClassDB::is_parent_class(expr_native, GDScript::get_class_static());
6349 }
6350 if (p_container.class_type == head && expr_script.is_valid() && expr_script->get_path() == self_path) {
6351 // Special case: container is self and expression is self script
6352 return true;
6353 }
6354 while (expr_class) {
6355 if (expr_class == p_container.class_type) {
6356 return true;
6357 }
6358 expr_class = expr_class->base_type.class_type;
6359 }
6360 return false;
6361 } break;
6362 case DataType::BUILTIN: // Already handled above
6363 case DataType::UNRESOLVED: // Not allowed, see above
6364 break;
6365 }
6366
6367 return false;
6368 }
6369
_get_default_value_for_type(const DataType & p_type,int p_line)6370 GDScriptParser::Node *GDScriptParser::_get_default_value_for_type(const DataType &p_type, int p_line) {
6371 Node *result;
6372
6373 if (p_type.has_type && p_type.kind == DataType::BUILTIN && p_type.builtin_type != Variant::NIL && p_type.builtin_type != Variant::OBJECT) {
6374 if (p_type.builtin_type == Variant::ARRAY) {
6375 result = alloc_node<ArrayNode>();
6376 } else if (p_type.builtin_type == Variant::DICTIONARY) {
6377 result = alloc_node<DictionaryNode>();
6378 } else {
6379 ConstantNode *c = alloc_node<ConstantNode>();
6380 Variant::CallError err;
6381 c->value = Variant::construct(p_type.builtin_type, NULL, 0, err);
6382 result = c;
6383 }
6384 } else {
6385 ConstantNode *c = alloc_node<ConstantNode>();
6386 c->value = Variant();
6387 result = c;
6388 }
6389
6390 result->line = p_line;
6391
6392 return result;
6393 }
6394
_reduce_node_type(Node * p_node)6395 GDScriptParser::DataType GDScriptParser::_reduce_node_type(Node *p_node) {
6396 #ifdef DEBUG_ENABLED
6397 if (p_node->get_datatype().has_type && p_node->type != Node::TYPE_ARRAY && p_node->type != Node::TYPE_DICTIONARY) {
6398 #else
6399 if (p_node->get_datatype().has_type) {
6400 #endif
6401 return p_node->get_datatype();
6402 }
6403
6404 DataType node_type;
6405
6406 switch (p_node->type) {
6407 case Node::TYPE_CONSTANT: {
6408 node_type = _type_from_variant(static_cast<ConstantNode *>(p_node)->value);
6409 } break;
6410 case Node::TYPE_TYPE: {
6411 TypeNode *tn = static_cast<TypeNode *>(p_node);
6412 node_type.has_type = true;
6413 node_type.is_meta_type = true;
6414 node_type.kind = DataType::BUILTIN;
6415 node_type.builtin_type = tn->vtype;
6416 } break;
6417 case Node::TYPE_ARRAY: {
6418 node_type.has_type = true;
6419 node_type.kind = DataType::BUILTIN;
6420 node_type.builtin_type = Variant::ARRAY;
6421 #ifdef DEBUG_ENABLED
6422 // Check stuff inside the array
6423 ArrayNode *an = static_cast<ArrayNode *>(p_node);
6424 for (int i = 0; i < an->elements.size(); i++) {
6425 _reduce_node_type(an->elements[i]);
6426 }
6427 #endif // DEBUG_ENABLED
6428 } break;
6429 case Node::TYPE_DICTIONARY: {
6430 node_type.has_type = true;
6431 node_type.kind = DataType::BUILTIN;
6432 node_type.builtin_type = Variant::DICTIONARY;
6433 #ifdef DEBUG_ENABLED
6434 // Check stuff inside the dictionarty
6435 DictionaryNode *dn = static_cast<DictionaryNode *>(p_node);
6436 for (int i = 0; i < dn->elements.size(); i++) {
6437 _reduce_node_type(dn->elements[i].key);
6438 _reduce_node_type(dn->elements[i].value);
6439 }
6440 #endif // DEBUG_ENABLED
6441 } break;
6442 case Node::TYPE_SELF: {
6443 node_type.has_type = true;
6444 node_type.kind = DataType::CLASS;
6445 node_type.class_type = current_class;
6446 node_type.is_constant = true;
6447 } break;
6448 case Node::TYPE_IDENTIFIER: {
6449 IdentifierNode *id = static_cast<IdentifierNode *>(p_node);
6450 if (id->declared_block) {
6451 node_type = id->declared_block->variables[id->name]->get_datatype();
6452 id->declared_block->variables[id->name]->usages += 1;
6453 } else if (id->name == "#match_value") {
6454 // It's a special id just for the match statetement, ignore
6455 break;
6456 } else if (current_function && current_function->arguments.find(id->name) >= 0) {
6457 int idx = current_function->arguments.find(id->name);
6458 node_type = current_function->argument_types[idx];
6459 } else {
6460 node_type = _reduce_identifier_type(NULL, id->name, id->line, false);
6461 }
6462 } break;
6463 case Node::TYPE_CAST: {
6464 CastNode *cn = static_cast<CastNode *>(p_node);
6465
6466 DataType source_type = _reduce_node_type(cn->source_node);
6467 cn->cast_type = _resolve_type(cn->cast_type, cn->line);
6468 if (source_type.has_type) {
6469
6470 bool valid = false;
6471 if (check_types) {
6472 if (cn->cast_type.kind == DataType::BUILTIN && source_type.kind == DataType::BUILTIN) {
6473 valid = Variant::can_convert(source_type.builtin_type, cn->cast_type.builtin_type);
6474 }
6475 if (cn->cast_type.kind != DataType::BUILTIN && source_type.kind != DataType::BUILTIN) {
6476 valid = _is_type_compatible(cn->cast_type, source_type) || _is_type_compatible(source_type, cn->cast_type);
6477 }
6478
6479 if (!valid) {
6480 _set_error("Invalid cast. Cannot convert from \"" + source_type.to_string() +
6481 "\" to \"" + cn->cast_type.to_string() + "\".",
6482 cn->line);
6483 return DataType();
6484 }
6485 }
6486 } else {
6487 #ifdef DEBUG_ENABLED
6488 _add_warning(GDScriptWarning::UNSAFE_CAST, cn->line, cn->cast_type.to_string());
6489 #endif // DEBUG_ENABLED
6490 _mark_line_as_unsafe(cn->line);
6491 }
6492
6493 node_type = cn->cast_type;
6494
6495 } break;
6496 case Node::TYPE_OPERATOR: {
6497 OperatorNode *op = static_cast<OperatorNode *>(p_node);
6498
6499 switch (op->op) {
6500 case OperatorNode::OP_CALL:
6501 case OperatorNode::OP_PARENT_CALL: {
6502 node_type = _reduce_function_call_type(op);
6503 } break;
6504 case OperatorNode::OP_YIELD: {
6505 if (op->arguments.size() == 2) {
6506 DataType base_type = _reduce_node_type(op->arguments[0]);
6507 DataType signal_type = _reduce_node_type(op->arguments[1]);
6508 // TODO: Check if signal exists when it's a constant
6509 if (base_type.has_type && base_type.kind == DataType::BUILTIN && base_type.builtin_type != Variant::NIL && base_type.builtin_type != Variant::OBJECT) {
6510 _set_error("The first argument of \"yield()\" must be an object.", op->line);
6511 return DataType();
6512 }
6513 if (signal_type.has_type && (signal_type.kind != DataType::BUILTIN || signal_type.builtin_type != Variant::STRING)) {
6514 _set_error("The second argument of \"yield()\" must be a string.", op->line);
6515 return DataType();
6516 }
6517 }
6518 // yield can return anything
6519 node_type.has_type = false;
6520 } break;
6521 case OperatorNode::OP_IS:
6522 case OperatorNode::OP_IS_BUILTIN: {
6523
6524 if (op->arguments.size() != 2) {
6525 _set_error("Parser bug: binary operation without 2 arguments.", op->line);
6526 ERR_FAIL_V(DataType());
6527 }
6528
6529 DataType value_type = _reduce_node_type(op->arguments[0]);
6530 DataType type_type = _reduce_node_type(op->arguments[1]);
6531
6532 if (check_types && type_type.has_type) {
6533 if (!type_type.is_meta_type && (type_type.kind != DataType::NATIVE || !ClassDB::is_parent_class(type_type.native_type, "Script"))) {
6534 _set_error("Invalid \"is\" test: the right operand isn't a type (neither a native type nor a script).", op->line);
6535 return DataType();
6536 }
6537 type_type.is_meta_type = false; // Test the actual type
6538 if (!_is_type_compatible(type_type, value_type) && !_is_type_compatible(value_type, type_type)) {
6539 if (op->op == OperatorNode::OP_IS) {
6540 _set_error("A value of type \"" + value_type.to_string() + "\" will never be an instance of \"" + type_type.to_string() + "\".", op->line);
6541 } else {
6542 _set_error("A value of type \"" + value_type.to_string() + "\" will never be of type \"" + type_type.to_string() + "\".", op->line);
6543 }
6544 return DataType();
6545 }
6546 }
6547
6548 node_type.has_type = true;
6549 node_type.is_constant = true;
6550 node_type.is_meta_type = false;
6551 node_type.kind = DataType::BUILTIN;
6552 node_type.builtin_type = Variant::BOOL;
6553 } break;
6554 // Unary operators
6555 case OperatorNode::OP_NEG:
6556 case OperatorNode::OP_POS:
6557 case OperatorNode::OP_NOT:
6558 case OperatorNode::OP_BIT_INVERT: {
6559
6560 DataType argument_type = _reduce_node_type(op->arguments[0]);
6561 if (!argument_type.has_type) {
6562 break;
6563 }
6564
6565 Variant::Operator var_op = _get_variant_operation(op->op);
6566 bool valid = false;
6567 node_type = _get_operation_type(var_op, argument_type, argument_type, valid);
6568
6569 if (check_types && !valid) {
6570 _set_error("Invalid operand type (\"" + argument_type.to_string() +
6571 "\") to unary operator \"" + Variant::get_operator_name(var_op) + "\".",
6572 op->line, op->column);
6573 return DataType();
6574 }
6575
6576 } break;
6577 // Binary operators
6578 case OperatorNode::OP_IN:
6579 case OperatorNode::OP_EQUAL:
6580 case OperatorNode::OP_NOT_EQUAL:
6581 case OperatorNode::OP_LESS:
6582 case OperatorNode::OP_LESS_EQUAL:
6583 case OperatorNode::OP_GREATER:
6584 case OperatorNode::OP_GREATER_EQUAL:
6585 case OperatorNode::OP_AND:
6586 case OperatorNode::OP_OR:
6587 case OperatorNode::OP_ADD:
6588 case OperatorNode::OP_SUB:
6589 case OperatorNode::OP_MUL:
6590 case OperatorNode::OP_DIV:
6591 case OperatorNode::OP_MOD:
6592 case OperatorNode::OP_SHIFT_LEFT:
6593 case OperatorNode::OP_SHIFT_RIGHT:
6594 case OperatorNode::OP_BIT_AND:
6595 case OperatorNode::OP_BIT_OR:
6596 case OperatorNode::OP_BIT_XOR: {
6597
6598 if (op->arguments.size() != 2) {
6599 _set_error("Parser bug: binary operation without 2 arguments.", op->line);
6600 ERR_FAIL_V(DataType());
6601 }
6602
6603 DataType argument_a_type = _reduce_node_type(op->arguments[0]);
6604 DataType argument_b_type = _reduce_node_type(op->arguments[1]);
6605 if (!argument_a_type.has_type || !argument_b_type.has_type) {
6606 _mark_line_as_unsafe(op->line);
6607 break;
6608 }
6609
6610 Variant::Operator var_op = _get_variant_operation(op->op);
6611 bool valid = false;
6612 node_type = _get_operation_type(var_op, argument_a_type, argument_b_type, valid);
6613
6614 if (check_types && !valid) {
6615 _set_error("Invalid operand types (\"" + argument_a_type.to_string() + "\" and \"" +
6616 argument_b_type.to_string() + "\") to operator \"" + Variant::get_operator_name(var_op) + "\".",
6617 op->line, op->column);
6618 return DataType();
6619 }
6620 #ifdef DEBUG_ENABLED
6621 if (var_op == Variant::OP_DIVIDE && argument_a_type.kind == DataType::BUILTIN && argument_a_type.builtin_type == Variant::INT &&
6622 argument_b_type.kind == DataType::BUILTIN && argument_b_type.builtin_type == Variant::INT) {
6623 _add_warning(GDScriptWarning::INTEGER_DIVISION, op->line);
6624 }
6625 #endif // DEBUG_ENABLED
6626
6627 } break;
6628 // Ternary operators
6629 case OperatorNode::OP_TERNARY_IF: {
6630 if (op->arguments.size() != 3) {
6631 _set_error("Parser bug: ternary operation without 3 arguments.");
6632 ERR_FAIL_V(DataType());
6633 }
6634
6635 DataType true_type = _reduce_node_type(op->arguments[1]);
6636 DataType false_type = _reduce_node_type(op->arguments[2]);
6637 // Check arguments[0] errors.
6638 _reduce_node_type(op->arguments[0]);
6639
6640 // If types are equal, then the expression is of the same type
6641 // If they are compatible, return the broader type
6642 if (true_type == false_type || _is_type_compatible(true_type, false_type)) {
6643 node_type = true_type;
6644 } else if (_is_type_compatible(false_type, true_type)) {
6645 node_type = false_type;
6646 } else {
6647 #ifdef DEBUG_ENABLED
6648 _add_warning(GDScriptWarning::INCOMPATIBLE_TERNARY, op->line);
6649 #endif // DEBUG_ENABLED
6650 }
6651 } break;
6652 // Assignment should never happen within an expression
6653 case OperatorNode::OP_ASSIGN:
6654 case OperatorNode::OP_ASSIGN_ADD:
6655 case OperatorNode::OP_ASSIGN_SUB:
6656 case OperatorNode::OP_ASSIGN_MUL:
6657 case OperatorNode::OP_ASSIGN_DIV:
6658 case OperatorNode::OP_ASSIGN_MOD:
6659 case OperatorNode::OP_ASSIGN_SHIFT_LEFT:
6660 case OperatorNode::OP_ASSIGN_SHIFT_RIGHT:
6661 case OperatorNode::OP_ASSIGN_BIT_AND:
6662 case OperatorNode::OP_ASSIGN_BIT_OR:
6663 case OperatorNode::OP_ASSIGN_BIT_XOR:
6664 case OperatorNode::OP_INIT_ASSIGN: {
6665
6666 _set_error("Assignment inside an expression isn't allowed (parser bug?).", op->line);
6667 return DataType();
6668
6669 } break;
6670 case OperatorNode::OP_INDEX_NAMED: {
6671 if (op->arguments.size() != 2) {
6672 _set_error("Parser bug: named index with invalid arguments.", op->line);
6673 ERR_FAIL_V(DataType());
6674 }
6675 if (op->arguments[1]->type != Node::TYPE_IDENTIFIER) {
6676 _set_error("Parser bug: named index without identifier argument.", op->line);
6677 ERR_FAIL_V(DataType());
6678 }
6679
6680 DataType base_type = _reduce_node_type(op->arguments[0]);
6681 IdentifierNode *member_id = static_cast<IdentifierNode *>(op->arguments[1]);
6682
6683 if (base_type.has_type) {
6684 if (check_types && base_type.kind == DataType::BUILTIN) {
6685 // Variant type, just test if it's possible
6686 DataType result;
6687 switch (base_type.builtin_type) {
6688 case Variant::NIL:
6689 case Variant::DICTIONARY: {
6690 result.has_type = false;
6691 } break;
6692 default: {
6693 Variant::CallError err;
6694 Variant temp = Variant::construct(base_type.builtin_type, NULL, 0, err);
6695
6696 bool valid = false;
6697 Variant res = temp.get(member_id->name.operator String(), &valid);
6698
6699 if (valid) {
6700 result = _type_from_variant(res);
6701 } else if (check_types) {
6702 _set_error("Can't get index \"" + String(member_id->name.operator String()) + "\" on base \"" +
6703 base_type.to_string() + "\".",
6704 op->line);
6705 return DataType();
6706 }
6707 } break;
6708 }
6709 result.is_constant = false;
6710 node_type = result;
6711 } else {
6712 node_type = _reduce_identifier_type(&base_type, member_id->name, op->line, true);
6713 #ifdef DEBUG_ENABLED
6714 if (!node_type.has_type) {
6715 _mark_line_as_unsafe(op->line);
6716 _add_warning(GDScriptWarning::UNSAFE_PROPERTY_ACCESS, op->line, member_id->name.operator String(), base_type.to_string());
6717 }
6718 #endif // DEBUG_ENABLED
6719 }
6720 } else {
6721 _mark_line_as_unsafe(op->line);
6722 }
6723 if (error_set) {
6724 return DataType();
6725 }
6726 } break;
6727 case OperatorNode::OP_INDEX: {
6728
6729 if (op->arguments[1]->type == Node::TYPE_CONSTANT) {
6730 ConstantNode *cn = static_cast<ConstantNode *>(op->arguments[1]);
6731 if (cn->value.get_type() == Variant::STRING) {
6732 // Treat this as named indexing
6733
6734 IdentifierNode *id = alloc_node<IdentifierNode>();
6735 id->name = cn->value.operator StringName();
6736 id->datatype = cn->datatype;
6737
6738 op->op = OperatorNode::OP_INDEX_NAMED;
6739 op->arguments.write[1] = id;
6740
6741 return _reduce_node_type(op);
6742 }
6743 }
6744
6745 DataType base_type = _reduce_node_type(op->arguments[0]);
6746 DataType index_type = _reduce_node_type(op->arguments[1]);
6747
6748 if (!base_type.has_type) {
6749 _mark_line_as_unsafe(op->line);
6750 break;
6751 }
6752
6753 if (check_types && index_type.has_type) {
6754 if (base_type.kind == DataType::BUILTIN) {
6755 // Check if indexing is valid
6756 bool error = index_type.kind != DataType::BUILTIN && base_type.builtin_type != Variant::DICTIONARY;
6757 if (!error) {
6758 switch (base_type.builtin_type) {
6759 // Expect int or real as index
6760 case Variant::POOL_BYTE_ARRAY:
6761 case Variant::POOL_COLOR_ARRAY:
6762 case Variant::POOL_INT_ARRAY:
6763 case Variant::POOL_REAL_ARRAY:
6764 case Variant::POOL_STRING_ARRAY:
6765 case Variant::POOL_VECTOR2_ARRAY:
6766 case Variant::POOL_VECTOR3_ARRAY:
6767 case Variant::ARRAY:
6768 case Variant::STRING: {
6769 error = index_type.builtin_type != Variant::INT && index_type.builtin_type != Variant::REAL;
6770 } break;
6771 // Expect String only
6772 case Variant::RECT2:
6773 case Variant::PLANE:
6774 case Variant::QUAT:
6775 case Variant::AABB:
6776 case Variant::OBJECT: {
6777 error = index_type.builtin_type != Variant::STRING;
6778 } break;
6779 // Expect String or number
6780 case Variant::VECTOR2:
6781 case Variant::VECTOR3:
6782 case Variant::TRANSFORM2D:
6783 case Variant::BASIS:
6784 case Variant::TRANSFORM: {
6785 error = index_type.builtin_type != Variant::INT && index_type.builtin_type != Variant::REAL &&
6786 index_type.builtin_type != Variant::STRING;
6787 } break;
6788 // Expect String or int
6789 case Variant::COLOR: {
6790 error = index_type.builtin_type != Variant::INT && index_type.builtin_type != Variant::STRING;
6791 } break;
6792 default: {
6793 }
6794 }
6795 }
6796 if (error) {
6797 _set_error("Invalid index type (" + index_type.to_string() + ") for base \"" + base_type.to_string() + "\".",
6798 op->line);
6799 return DataType();
6800 }
6801
6802 if (op->arguments[1]->type == GDScriptParser::Node::TYPE_CONSTANT) {
6803 ConstantNode *cn = static_cast<ConstantNode *>(op->arguments[1]);
6804 // Index is a constant, just try it if possible
6805 switch (base_type.builtin_type) {
6806 // Arrays/string have variable indexing, can't test directly
6807 case Variant::STRING:
6808 case Variant::ARRAY:
6809 case Variant::DICTIONARY:
6810 case Variant::POOL_BYTE_ARRAY:
6811 case Variant::POOL_COLOR_ARRAY:
6812 case Variant::POOL_INT_ARRAY:
6813 case Variant::POOL_REAL_ARRAY:
6814 case Variant::POOL_STRING_ARRAY:
6815 case Variant::POOL_VECTOR2_ARRAY:
6816 case Variant::POOL_VECTOR3_ARRAY: {
6817 break;
6818 }
6819 default: {
6820 Variant::CallError err;
6821 Variant temp = Variant::construct(base_type.builtin_type, NULL, 0, err);
6822
6823 bool valid = false;
6824 Variant res = temp.get(cn->value, &valid);
6825
6826 if (valid) {
6827 node_type = _type_from_variant(res);
6828 node_type.is_constant = false;
6829 } else if (check_types) {
6830 _set_error("Can't get index \"" + String(cn->value) + "\" on base \"" +
6831 base_type.to_string() + "\".",
6832 op->line);
6833 return DataType();
6834 }
6835 } break;
6836 }
6837 } else {
6838 _mark_line_as_unsafe(op->line);
6839 }
6840 } else if (!for_completion && (index_type.kind != DataType::BUILTIN || index_type.builtin_type != Variant::STRING)) {
6841 _set_error("Only strings can be used as an index in the base type \"" + base_type.to_string() + "\".", op->line);
6842 return DataType();
6843 }
6844 }
6845 if (check_types && !node_type.has_type && base_type.kind == DataType::BUILTIN) {
6846 // Can infer indexing type for some variant types
6847 DataType result;
6848 result.has_type = true;
6849 result.kind = DataType::BUILTIN;
6850 switch (base_type.builtin_type) {
6851 // Can't index at all
6852 case Variant::NIL:
6853 case Variant::BOOL:
6854 case Variant::INT:
6855 case Variant::REAL:
6856 case Variant::NODE_PATH:
6857 case Variant::_RID: {
6858 _set_error("Can't index on a value of type \"" + base_type.to_string() + "\".", op->line);
6859 return DataType();
6860 } break;
6861 // Return int
6862 case Variant::POOL_BYTE_ARRAY:
6863 case Variant::POOL_INT_ARRAY: {
6864 result.builtin_type = Variant::INT;
6865 } break;
6866 // Return real
6867 case Variant::POOL_REAL_ARRAY:
6868 case Variant::VECTOR2:
6869 case Variant::VECTOR3:
6870 case Variant::QUAT: {
6871 result.builtin_type = Variant::REAL;
6872 } break;
6873 // Return color
6874 case Variant::POOL_COLOR_ARRAY: {
6875 result.builtin_type = Variant::COLOR;
6876 } break;
6877 // Return string
6878 case Variant::POOL_STRING_ARRAY:
6879 case Variant::STRING: {
6880 result.builtin_type = Variant::STRING;
6881 } break;
6882 // Return Vector2
6883 case Variant::POOL_VECTOR2_ARRAY:
6884 case Variant::TRANSFORM2D:
6885 case Variant::RECT2: {
6886 result.builtin_type = Variant::VECTOR2;
6887 } break;
6888 // Return Vector3
6889 case Variant::POOL_VECTOR3_ARRAY:
6890 case Variant::AABB:
6891 case Variant::BASIS: {
6892 result.builtin_type = Variant::VECTOR3;
6893 } break;
6894 // Depends on the index
6895 case Variant::TRANSFORM:
6896 case Variant::PLANE:
6897 case Variant::COLOR:
6898 default: {
6899 result.has_type = false;
6900 } break;
6901 }
6902 node_type = result;
6903 }
6904 } break;
6905 default: {
6906 _set_error("Parser bug: unhandled operation.", op->line);
6907 ERR_FAIL_V(DataType());
6908 }
6909 }
6910 } break;
6911 default: {
6912 }
6913 }
6914
6915 node_type = _resolve_type(node_type, p_node->line);
6916 p_node->set_datatype(node_type);
6917 return node_type;
6918 }
6919
6920 bool GDScriptParser::_get_function_signature(DataType &p_base_type, const StringName &p_function, DataType &r_return_type, List<DataType> &r_arg_types, int &r_default_arg_count, bool &r_static, bool &r_vararg) const {
6921
6922 r_static = false;
6923 r_default_arg_count = 0;
6924
6925 DataType original_type = p_base_type;
6926 ClassNode *base = NULL;
6927 FunctionNode *callee = NULL;
6928
6929 if (p_base_type.kind == DataType::CLASS) {
6930 base = p_base_type.class_type;
6931 }
6932
6933 // Look up the current file (parse tree)
6934 while (!callee && base) {
6935 for (int i = 0; i < base->static_functions.size(); i++) {
6936 FunctionNode *func = base->static_functions[i];
6937 if (p_function == func->name) {
6938 r_static = true;
6939 callee = func;
6940 break;
6941 }
6942 }
6943 if (!callee && !p_base_type.is_meta_type) {
6944 for (int i = 0; i < base->functions.size(); i++) {
6945 FunctionNode *func = base->functions[i];
6946 if (p_function == func->name) {
6947 callee = func;
6948 break;
6949 }
6950 }
6951 }
6952 p_base_type = base->base_type;
6953 if (p_base_type.kind == DataType::CLASS) {
6954 base = p_base_type.class_type;
6955 } else {
6956 break;
6957 }
6958 }
6959
6960 if (callee) {
6961 r_return_type = callee->get_datatype();
6962 for (int i = 0; i < callee->argument_types.size(); i++) {
6963 r_arg_types.push_back(callee->argument_types[i]);
6964 }
6965 r_default_arg_count = callee->default_values.size();
6966 return true;
6967 }
6968
6969 // Nothing in current file, check parent script
6970 Ref<GDScript> base_gdscript;
6971 Ref<Script> base_script;
6972 StringName native;
6973 if (p_base_type.kind == DataType::GDSCRIPT) {
6974 base_gdscript = p_base_type.script_type;
6975 if (base_gdscript.is_null() || !base_gdscript->is_valid()) {
6976 // GDScript wasn't properly compíled, don't bother trying
6977 return false;
6978 }
6979 } else if (p_base_type.kind == DataType::SCRIPT) {
6980 base_script = p_base_type.script_type;
6981 } else if (p_base_type.kind == DataType::NATIVE) {
6982 native = p_base_type.native_type;
6983 }
6984
6985 while (base_gdscript.is_valid()) {
6986 native = base_gdscript->get_instance_base_type();
6987
6988 Map<StringName, GDScriptFunction *> funcs = base_gdscript->get_member_functions();
6989
6990 if (funcs.has(p_function)) {
6991 GDScriptFunction *f = funcs[p_function];
6992 r_static = f->is_static();
6993 r_default_arg_count = f->get_default_argument_count();
6994 r_return_type = _type_from_gdtype(f->get_return_type());
6995 for (int i = 0; i < f->get_argument_count(); i++) {
6996 r_arg_types.push_back(_type_from_gdtype(f->get_argument_type(i)));
6997 }
6998 return true;
6999 }
7000
7001 base_gdscript = base_gdscript->get_base_script();
7002 }
7003
7004 while (base_script.is_valid()) {
7005 native = base_script->get_instance_base_type();
7006 MethodInfo mi = base_script->get_method_info(p_function);
7007
7008 if (!(mi == MethodInfo())) {
7009 r_return_type = _type_from_property(mi.return_val, false);
7010 r_default_arg_count = mi.default_arguments.size();
7011 for (List<PropertyInfo>::Element *E = mi.arguments.front(); E; E = E->next()) {
7012 r_arg_types.push_back(_type_from_property(E->get()));
7013 }
7014 return true;
7015 }
7016 base_script = base_script->get_base_script();
7017 }
7018
7019 if (native == StringName()) {
7020 // Empty native class, might happen in some Script implementations
7021 // Just ignore it
7022 return false;
7023 }
7024
7025 #ifdef DEBUG_METHODS_ENABLED
7026
7027 // Only native remains
7028 if (!ClassDB::class_exists(native)) {
7029 native = "_" + native.operator String();
7030 }
7031 if (!ClassDB::class_exists(native)) {
7032 if (!check_types) return false;
7033 ERR_FAIL_V_MSG(false, "Parser bug: Class '" + String(native) + "' not found.");
7034 }
7035
7036 MethodBind *method = ClassDB::get_method(native, p_function);
7037
7038 if (!method) {
7039 // Try virtual methods
7040 List<MethodInfo> virtuals;
7041 ClassDB::get_virtual_methods(native, &virtuals);
7042
7043 for (const List<MethodInfo>::Element *E = virtuals.front(); E; E = E->next()) {
7044 const MethodInfo &mi = E->get();
7045 if (mi.name == p_function) {
7046 r_default_arg_count = mi.default_arguments.size();
7047 for (const List<PropertyInfo>::Element *pi = mi.arguments.front(); pi; pi = pi->next()) {
7048 r_arg_types.push_back(_type_from_property(pi->get()));
7049 }
7050 r_return_type = _type_from_property(mi.return_val, false);
7051 r_vararg = mi.flags & METHOD_FLAG_VARARG;
7052 return true;
7053 }
7054 }
7055
7056 // If the base is a script, it might be trying to access members of the Script class itself
7057 if (original_type.is_meta_type && !(p_function == "new") && (original_type.kind == DataType::SCRIPT || original_type.kind == DataType::GDSCRIPT)) {
7058 method = ClassDB::get_method(original_type.script_type->get_class_name(), p_function);
7059
7060 if (method) {
7061 r_static = true;
7062 } else {
7063 // Try virtual methods of the script type
7064 virtuals.clear();
7065 ClassDB::get_virtual_methods(original_type.script_type->get_class_name(), &virtuals);
7066 for (const List<MethodInfo>::Element *E = virtuals.front(); E; E = E->next()) {
7067 const MethodInfo &mi = E->get();
7068 if (mi.name == p_function) {
7069 r_default_arg_count = mi.default_arguments.size();
7070 for (const List<PropertyInfo>::Element *pi = mi.arguments.front(); pi; pi = pi->next()) {
7071 r_arg_types.push_back(_type_from_property(pi->get()));
7072 }
7073 r_return_type = _type_from_property(mi.return_val, false);
7074 r_static = true;
7075 r_vararg = mi.flags & METHOD_FLAG_VARARG;
7076 return true;
7077 }
7078 }
7079 return false;
7080 }
7081 } else {
7082 return false;
7083 }
7084 }
7085
7086 r_default_arg_count = method->get_default_argument_count();
7087 if (method->get_name() == "get_script") {
7088 r_return_type = DataType(); // Variant for now and let runtime decide.
7089 } else {
7090 r_return_type = _type_from_property(method->get_return_info(), false);
7091 }
7092 r_vararg = method->is_vararg();
7093
7094 for (int i = 0; i < method->get_argument_count(); i++) {
7095 r_arg_types.push_back(_type_from_property(method->get_argument_info(i)));
7096 }
7097 return true;
7098 #else
7099 return false;
7100 #endif
7101 }
7102
7103 GDScriptParser::DataType GDScriptParser::_reduce_function_call_type(const OperatorNode *p_call) {
7104 if (p_call->arguments.size() < 1) {
7105 _set_error("Parser bug: function call without enough arguments.", p_call->line);
7106 ERR_FAIL_V(DataType());
7107 }
7108
7109 DataType return_type;
7110 List<DataType> arg_types;
7111 int default_args_count = 0;
7112 int arg_count = p_call->arguments.size();
7113 String callee_name;
7114 bool is_vararg = false;
7115
7116 switch (p_call->arguments[0]->type) {
7117 case GDScriptParser::Node::TYPE_TYPE: {
7118 // Built-in constructor, special case
7119 TypeNode *tn = static_cast<TypeNode *>(p_call->arguments[0]);
7120
7121 Vector<DataType> par_types;
7122 par_types.resize(p_call->arguments.size() - 1);
7123 for (int i = 1; i < p_call->arguments.size(); i++) {
7124 par_types.write[i - 1] = _reduce_node_type(p_call->arguments[i]);
7125 }
7126
7127 if (error_set) return DataType();
7128
7129 // Special case: check copy constructor. Those are defined implicitly in Variant.
7130 if (par_types.size() == 1) {
7131 if (!par_types[0].has_type || (par_types[0].kind == DataType::BUILTIN && par_types[0].builtin_type == tn->vtype)) {
7132 DataType result;
7133 result.has_type = true;
7134 result.kind = DataType::BUILTIN;
7135 result.builtin_type = tn->vtype;
7136 return result;
7137 }
7138 }
7139
7140 bool match = false;
7141 List<MethodInfo> constructors;
7142 Variant::get_constructor_list(tn->vtype, &constructors);
7143 PropertyInfo return_type2;
7144
7145 for (List<MethodInfo>::Element *E = constructors.front(); E; E = E->next()) {
7146 MethodInfo &mi = E->get();
7147
7148 if (p_call->arguments.size() - 1 < mi.arguments.size() - mi.default_arguments.size()) {
7149 continue;
7150 }
7151 if (p_call->arguments.size() - 1 > mi.arguments.size()) {
7152 continue;
7153 }
7154
7155 bool types_match = true;
7156 for (int i = 0; i < par_types.size(); i++) {
7157 DataType arg_type;
7158 if (mi.arguments[i].type != Variant::NIL) {
7159 arg_type.has_type = true;
7160 arg_type.kind = mi.arguments[i].type == Variant::OBJECT ? DataType::NATIVE : DataType::BUILTIN;
7161 arg_type.builtin_type = mi.arguments[i].type;
7162 arg_type.native_type = mi.arguments[i].class_name;
7163 }
7164
7165 if (!_is_type_compatible(arg_type, par_types[i], true)) {
7166 types_match = false;
7167 break;
7168 } else {
7169 #ifdef DEBUG_ENABLED
7170 if (arg_type.kind == DataType::BUILTIN && arg_type.builtin_type == Variant::INT && par_types[i].kind == DataType::BUILTIN && par_types[i].builtin_type == Variant::REAL) {
7171 _add_warning(GDScriptWarning::NARROWING_CONVERSION, p_call->line, Variant::get_type_name(tn->vtype));
7172 }
7173 if (par_types[i].may_yield && p_call->arguments[i + 1]->type == Node::TYPE_OPERATOR) {
7174 _add_warning(GDScriptWarning::FUNCTION_MAY_YIELD, p_call->line, _find_function_name(static_cast<OperatorNode *>(p_call->arguments[i + 1])));
7175 }
7176 #endif // DEBUG_ENABLED
7177 }
7178 }
7179
7180 if (types_match) {
7181 match = true;
7182 return_type2 = mi.return_val;
7183 break;
7184 }
7185 }
7186
7187 if (match) {
7188 return _type_from_property(return_type2, false);
7189 } else if (check_types) {
7190 String err = "No constructor of '";
7191 err += Variant::get_type_name(tn->vtype);
7192 err += "' matches the signature '";
7193 err += Variant::get_type_name(tn->vtype) + "(";
7194 for (int i = 0; i < par_types.size(); i++) {
7195 if (i > 0) err += ", ";
7196 err += par_types[i].to_string();
7197 }
7198 err += ")'.";
7199 _set_error(err, p_call->line, p_call->column);
7200 return DataType();
7201 }
7202 return DataType();
7203 } break;
7204 case GDScriptParser::Node::TYPE_BUILT_IN_FUNCTION: {
7205 BuiltInFunctionNode *func = static_cast<BuiltInFunctionNode *>(p_call->arguments[0]);
7206 MethodInfo mi = GDScriptFunctions::get_info(func->function);
7207
7208 return_type = _type_from_property(mi.return_val, false);
7209
7210 // Check all arguments beforehand to solve warnings
7211 for (int i = 1; i < p_call->arguments.size(); i++) {
7212 _reduce_node_type(p_call->arguments[i]);
7213 }
7214
7215 // Check arguments
7216
7217 is_vararg = mi.flags & METHOD_FLAG_VARARG;
7218
7219 default_args_count = mi.default_arguments.size();
7220 callee_name = mi.name;
7221 arg_count -= 1;
7222
7223 // Check each argument type
7224 for (List<PropertyInfo>::Element *E = mi.arguments.front(); E; E = E->next()) {
7225 arg_types.push_back(_type_from_property(E->get()));
7226 }
7227 } break;
7228 default: {
7229 if (p_call->op == OperatorNode::OP_CALL && p_call->arguments.size() < 2) {
7230 _set_error("Parser bug: self method call without enough arguments.", p_call->line);
7231 ERR_FAIL_V(DataType());
7232 }
7233
7234 int arg_id = p_call->op == OperatorNode::OP_CALL ? 1 : 0;
7235
7236 if (p_call->arguments[arg_id]->type != Node::TYPE_IDENTIFIER) {
7237 _set_error("Parser bug: invalid function call argument.", p_call->line);
7238 ERR_FAIL_V(DataType());
7239 }
7240
7241 // Check all arguments beforehand to solve warnings
7242 for (int i = arg_id + 1; i < p_call->arguments.size(); i++) {
7243 _reduce_node_type(p_call->arguments[i]);
7244 }
7245
7246 IdentifierNode *func_id = static_cast<IdentifierNode *>(p_call->arguments[arg_id]);
7247 callee_name = func_id->name;
7248 arg_count -= 1 + arg_id;
7249
7250 DataType base_type;
7251 if (p_call->op == OperatorNode::OP_PARENT_CALL) {
7252 base_type = current_class->base_type;
7253 } else {
7254 base_type = _reduce_node_type(p_call->arguments[0]);
7255 }
7256
7257 if (!base_type.has_type || (base_type.kind == DataType::BUILTIN && base_type.builtin_type == Variant::NIL)) {
7258 _mark_line_as_unsafe(p_call->line);
7259 return DataType();
7260 }
7261
7262 if (base_type.kind == DataType::BUILTIN) {
7263 Variant::CallError err;
7264 Variant tmp = Variant::construct(base_type.builtin_type, NULL, 0, err);
7265
7266 if (check_types) {
7267 if (!tmp.has_method(callee_name)) {
7268 _set_error("The method \"" + callee_name + "\" isn't declared on base \"" + base_type.to_string() + "\".", p_call->line);
7269 return DataType();
7270 }
7271
7272 default_args_count = Variant::get_method_default_arguments(base_type.builtin_type, callee_name).size();
7273 const Vector<Variant::Type> &var_arg_types = Variant::get_method_argument_types(base_type.builtin_type, callee_name);
7274
7275 for (int i = 0; i < var_arg_types.size(); i++) {
7276 DataType argtype;
7277 if (var_arg_types[i] != Variant::NIL) {
7278 argtype.has_type = true;
7279 argtype.kind = DataType::BUILTIN;
7280 argtype.builtin_type = var_arg_types[i];
7281 }
7282 arg_types.push_back(argtype);
7283 }
7284 }
7285
7286 bool rets = false;
7287 return_type.has_type = true;
7288 return_type.kind = DataType::BUILTIN;
7289 return_type.builtin_type = Variant::get_method_return_type(base_type.builtin_type, callee_name, &rets);
7290 // If the method returns, but it might return any type, (Variant::NIL), pretend we don't know the type.
7291 // At least make sure we know that it returns
7292 if (rets && return_type.builtin_type == Variant::NIL) {
7293 return_type.has_type = false;
7294 }
7295 break;
7296 }
7297
7298 DataType original_type = base_type;
7299 bool is_initializer = callee_name == "new";
7300 bool is_get_script = p_call->arguments[0]->type == Node::TYPE_SELF && callee_name == "get_script";
7301 bool is_static = false;
7302 bool valid = false;
7303
7304 if (is_initializer && original_type.is_meta_type) {
7305 // Try to check it as initializer
7306 base_type = original_type;
7307 callee_name = "_init";
7308 base_type.is_meta_type = false;
7309
7310 valid = _get_function_signature(base_type, callee_name, return_type, arg_types,
7311 default_args_count, is_static, is_vararg);
7312
7313 return_type = original_type;
7314 return_type.is_meta_type = false;
7315
7316 valid = true; // There's always an initializer, we can assume this is true
7317 }
7318
7319 if (is_get_script) {
7320 // get_script() can be considered a meta-type.
7321 return_type.kind = DataType::CLASS;
7322 return_type.class_type = static_cast<ClassNode *>(head);
7323 return_type.is_meta_type = true;
7324 valid = true;
7325 }
7326
7327 if (!valid) {
7328 base_type = original_type;
7329 return_type = DataType();
7330 valid = _get_function_signature(base_type, callee_name, return_type, arg_types,
7331 default_args_count, is_static, is_vararg);
7332 }
7333
7334 if (!valid) {
7335 #ifdef DEBUG_ENABLED
7336 if (p_call->arguments[0]->type == Node::TYPE_SELF) {
7337 _set_error("The method \"" + callee_name + "\" isn't declared in the current class.", p_call->line);
7338 return DataType();
7339 }
7340 DataType tmp_type;
7341 valid = _get_member_type(original_type, func_id->name, tmp_type);
7342 if (valid) {
7343 if (tmp_type.is_constant) {
7344 _add_warning(GDScriptWarning::CONSTANT_USED_AS_FUNCTION, p_call->line, callee_name, original_type.to_string());
7345 } else {
7346 _add_warning(GDScriptWarning::PROPERTY_USED_AS_FUNCTION, p_call->line, callee_name, original_type.to_string());
7347 }
7348 }
7349 _add_warning(GDScriptWarning::UNSAFE_METHOD_ACCESS, p_call->line, callee_name, original_type.to_string());
7350 _mark_line_as_unsafe(p_call->line);
7351 #endif // DEBUG_ENABLED
7352 return DataType();
7353 }
7354
7355 #ifdef DEBUG_ENABLED
7356 if (current_function && !for_completion && !is_static && p_call->arguments[0]->type == Node::TYPE_SELF && current_function->_static) {
7357 _set_error("Can't call non-static function from a static function.", p_call->line);
7358 return DataType();
7359 }
7360
7361 if (check_types && !is_static && !is_initializer && base_type.is_meta_type) {
7362 _set_error("Non-static function \"" + String(callee_name) + "\" can only be called from an instance.", p_call->line);
7363 return DataType();
7364 }
7365
7366 // Check signal emission for warnings
7367 if (callee_name == "emit_signal" && p_call->op == OperatorNode::OP_CALL && p_call->arguments[0]->type == Node::TYPE_SELF && p_call->arguments.size() >= 3 && p_call->arguments[2]->type == Node::TYPE_CONSTANT) {
7368 ConstantNode *sig = static_cast<ConstantNode *>(p_call->arguments[2]);
7369 String emitted = sig->value.get_type() == Variant::STRING ? sig->value.operator String() : "";
7370 for (int i = 0; i < current_class->_signals.size(); i++) {
7371 if (current_class->_signals[i].name == emitted) {
7372 current_class->_signals.write[i].emissions += 1;
7373 break;
7374 }
7375 }
7376 }
7377 #endif // DEBUG_ENABLED
7378 } break;
7379 }
7380
7381 #ifdef DEBUG_ENABLED
7382 if (!check_types) {
7383 return return_type;
7384 }
7385
7386 if (arg_count < arg_types.size() - default_args_count) {
7387 _set_error("Too few arguments for \"" + callee_name + "()\" call. Expected at least " + itos(arg_types.size() - default_args_count) + ".", p_call->line);
7388 return return_type;
7389 }
7390 if (!is_vararg && arg_count > arg_types.size()) {
7391 _set_error("Too many arguments for \"" + callee_name + "()\" call. Expected at most " + itos(arg_types.size()) + ".", p_call->line);
7392 return return_type;
7393 }
7394
7395 int arg_diff = p_call->arguments.size() - arg_count;
7396 for (int i = arg_diff; i < p_call->arguments.size(); i++) {
7397 DataType par_type = _reduce_node_type(p_call->arguments[i]);
7398
7399 if ((i - arg_diff) >= arg_types.size()) {
7400 continue;
7401 }
7402
7403 DataType arg_type = arg_types[i - arg_diff];
7404
7405 if (!par_type.has_type) {
7406 _mark_line_as_unsafe(p_call->line);
7407 if (par_type.may_yield && p_call->arguments[i]->type == Node::TYPE_OPERATOR) {
7408 _add_warning(GDScriptWarning::FUNCTION_MAY_YIELD, p_call->line, _find_function_name(static_cast<OperatorNode *>(p_call->arguments[i])));
7409 }
7410 } else if (!_is_type_compatible(arg_types[i - arg_diff], par_type, true)) {
7411 // Supertypes are acceptable for dynamic compliance
7412 if (!_is_type_compatible(par_type, arg_types[i - arg_diff])) {
7413 _set_error("At \"" + callee_name + "()\" call, argument " + itos(i - arg_diff + 1) + ". The passed argument's type (" +
7414 par_type.to_string() + ") doesn't match the function's expected argument type (" +
7415 arg_types[i - arg_diff].to_string() + ").",
7416 p_call->line);
7417 return DataType();
7418 } else {
7419 _mark_line_as_unsafe(p_call->line);
7420 }
7421 } else {
7422 if (arg_type.kind == DataType::BUILTIN && arg_type.builtin_type == Variant::INT && par_type.kind == DataType::BUILTIN && par_type.builtin_type == Variant::REAL) {
7423 _add_warning(GDScriptWarning::NARROWING_CONVERSION, p_call->line, callee_name);
7424 }
7425 }
7426 }
7427
7428 #endif // DEBUG_ENABLED
7429
7430 return return_type;
7431 }
7432
7433 bool GDScriptParser::_get_member_type(const DataType &p_base_type, const StringName &p_member, DataType &r_member_type, bool *r_is_const) const {
7434 DataType base_type = p_base_type;
7435
7436 // Check classes in current file
7437 ClassNode *base = NULL;
7438 if (base_type.kind == DataType::CLASS) {
7439 base = base_type.class_type;
7440 }
7441
7442 while (base) {
7443 if (base->constant_expressions.has(p_member)) {
7444 if (r_is_const)
7445 *r_is_const = true;
7446 r_member_type = base->constant_expressions[p_member].expression->get_datatype();
7447 return true;
7448 }
7449
7450 if (!base_type.is_meta_type) {
7451 for (int i = 0; i < base->variables.size(); i++) {
7452 if (base->variables[i].identifier == p_member) {
7453 r_member_type = base->variables[i].data_type;
7454 base->variables.write[i].usages += 1;
7455 return true;
7456 }
7457 }
7458 } else {
7459 for (int i = 0; i < base->subclasses.size(); i++) {
7460 ClassNode *c = base->subclasses[i];
7461 if (c->name == p_member) {
7462 DataType class_type;
7463 class_type.has_type = true;
7464 class_type.is_constant = true;
7465 class_type.is_meta_type = true;
7466 class_type.kind = DataType::CLASS;
7467 class_type.class_type = c;
7468 r_member_type = class_type;
7469 return true;
7470 }
7471 }
7472 }
7473
7474 base_type = base->base_type;
7475 if (base_type.kind == DataType::CLASS) {
7476 base = base_type.class_type;
7477 } else {
7478 break;
7479 }
7480 }
7481
7482 Ref<GDScript> gds;
7483 if (base_type.kind == DataType::GDSCRIPT) {
7484 gds = base_type.script_type;
7485 if (gds.is_null() || !gds->is_valid()) {
7486 // GDScript wasn't properly compíled, don't bother trying
7487 return false;
7488 }
7489 }
7490
7491 Ref<Script> scr;
7492 if (base_type.kind == DataType::SCRIPT) {
7493 scr = base_type.script_type;
7494 }
7495
7496 StringName native;
7497 if (base_type.kind == DataType::NATIVE) {
7498 native = base_type.native_type;
7499 }
7500
7501 // Check GDScripts
7502 while (gds.is_valid()) {
7503 if (gds->get_constants().has(p_member)) {
7504 Variant c = gds->get_constants()[p_member];
7505 r_member_type = _type_from_variant(c);
7506 return true;
7507 }
7508
7509 if (!base_type.is_meta_type) {
7510 if (gds->get_members().has(p_member)) {
7511 r_member_type = _type_from_gdtype(gds->get_member_type(p_member));
7512 return true;
7513 }
7514 }
7515
7516 native = gds->get_instance_base_type();
7517 if (gds->get_base_script().is_valid()) {
7518 gds = gds->get_base_script();
7519 scr = gds->get_base_script();
7520 bool is_meta = base_type.is_meta_type;
7521 base_type = _type_from_variant(scr.operator Variant());
7522 base_type.is_meta_type = is_meta;
7523 } else {
7524 break;
7525 }
7526 }
7527
7528 #define IS_USAGE_MEMBER(m_usage) (!(m_usage & (PROPERTY_USAGE_GROUP | PROPERTY_USAGE_CATEGORY)))
7529
7530 // Check other script types
7531 while (scr.is_valid()) {
7532 Map<StringName, Variant> constants;
7533 scr->get_constants(&constants);
7534 if (constants.has(p_member)) {
7535 r_member_type = _type_from_variant(constants[p_member]);
7536 return true;
7537 }
7538
7539 List<PropertyInfo> properties;
7540 scr->get_script_property_list(&properties);
7541 for (List<PropertyInfo>::Element *E = properties.front(); E; E = E->next()) {
7542 if (E->get().name == p_member && IS_USAGE_MEMBER(E->get().usage)) {
7543 r_member_type = _type_from_property(E->get());
7544 return true;
7545 }
7546 }
7547
7548 base_type = _type_from_variant(scr.operator Variant());
7549 native = scr->get_instance_base_type();
7550 scr = scr->get_base_script();
7551 }
7552
7553 if (native == StringName()) {
7554 // Empty native class, might happen in some Script implementations
7555 // Just ignore it
7556 return false;
7557 }
7558
7559 // Check ClassDB
7560 if (!ClassDB::class_exists(native)) {
7561 native = "_" + native.operator String();
7562 }
7563 if (!ClassDB::class_exists(native)) {
7564 if (!check_types) return false;
7565 ERR_FAIL_V_MSG(false, "Parser bug: Class \"" + String(native) + "\" not found.");
7566 }
7567
7568 bool valid = false;
7569 ClassDB::get_integer_constant(native, p_member, &valid);
7570 if (valid) {
7571 DataType ct;
7572 ct.has_type = true;
7573 ct.is_constant = true;
7574 ct.kind = DataType::BUILTIN;
7575 ct.builtin_type = Variant::INT;
7576 r_member_type = ct;
7577 return true;
7578 }
7579
7580 if (!base_type.is_meta_type) {
7581 List<PropertyInfo> properties;
7582 ClassDB::get_property_list(native, &properties);
7583 for (List<PropertyInfo>::Element *E = properties.front(); E; E = E->next()) {
7584 if (E->get().name == p_member && IS_USAGE_MEMBER(E->get().usage)) {
7585 // Check if a getter exists
7586 StringName getter_name = ClassDB::get_property_getter(native, p_member);
7587 if (getter_name != StringName()) {
7588 // Use the getter return type
7589 #ifdef DEBUG_METHODS_ENABLED
7590 MethodBind *getter_method = ClassDB::get_method(native, getter_name);
7591 if (getter_method) {
7592 r_member_type = _type_from_property(getter_method->get_return_info());
7593 } else {
7594 r_member_type = DataType();
7595 }
7596 #else
7597 r_member_type = DataType();
7598 #endif
7599 } else {
7600 r_member_type = _type_from_property(E->get());
7601 }
7602 return true;
7603 }
7604 }
7605 }
7606
7607 // If the base is a script, it might be trying to access members of the Script class itself
7608 if (p_base_type.is_meta_type && (p_base_type.kind == DataType::SCRIPT || p_base_type.kind == DataType::GDSCRIPT)) {
7609 native = p_base_type.script_type->get_class_name();
7610 ClassDB::get_integer_constant(native, p_member, &valid);
7611 if (valid) {
7612 DataType ct;
7613 ct.has_type = true;
7614 ct.is_constant = true;
7615 ct.kind = DataType::BUILTIN;
7616 ct.builtin_type = Variant::INT;
7617 r_member_type = ct;
7618 return true;
7619 }
7620
7621 List<PropertyInfo> properties;
7622 ClassDB::get_property_list(native, &properties);
7623 for (List<PropertyInfo>::Element *E = properties.front(); E; E = E->next()) {
7624 if (E->get().name == p_member && IS_USAGE_MEMBER(E->get().usage)) {
7625 // Check if a getter exists
7626 StringName getter_name = ClassDB::get_property_getter(native, p_member);
7627 if (getter_name != StringName()) {
7628 // Use the getter return type
7629 #ifdef DEBUG_METHODS_ENABLED
7630 MethodBind *getter_method = ClassDB::get_method(native, getter_name);
7631 if (getter_method) {
7632 r_member_type = _type_from_property(getter_method->get_return_info());
7633 } else {
7634 r_member_type = DataType();
7635 }
7636 #else
7637 r_member_type = DataType();
7638 #endif
7639 } else {
7640 r_member_type = _type_from_property(E->get());
7641 }
7642 return true;
7643 }
7644 }
7645 }
7646 #undef IS_USAGE_MEMBER
7647
7648 return false;
7649 }
7650
7651 GDScriptParser::DataType GDScriptParser::_reduce_identifier_type(const DataType *p_base_type, const StringName &p_identifier, int p_line, bool p_is_indexing) {
7652
7653 if (p_base_type && !p_base_type->has_type) {
7654 return DataType();
7655 }
7656
7657 DataType base_type;
7658 DataType member_type;
7659
7660 if (!p_base_type) {
7661 base_type.has_type = true;
7662 base_type.is_constant = true;
7663 base_type.kind = DataType::CLASS;
7664 base_type.class_type = current_class;
7665 } else {
7666 base_type = DataType(*p_base_type);
7667 }
7668
7669 bool is_const = false;
7670 if (_get_member_type(base_type, p_identifier, member_type, &is_const)) {
7671 if (!p_base_type && current_function && current_function->_static && !is_const) {
7672 _set_error("Can't access member variable (\"" + p_identifier.operator String() + "\") from a static function.", p_line);
7673 return DataType();
7674 }
7675 return member_type;
7676 }
7677
7678 if (p_is_indexing) {
7679 // Don't look for globals since this is an indexed identifier
7680 return DataType();
7681 }
7682
7683 if (!p_base_type) {
7684 // Possibly this is a global, check before failing
7685
7686 if (ClassDB::class_exists(p_identifier) || ClassDB::class_exists("_" + p_identifier.operator String())) {
7687 DataType result;
7688 result.has_type = true;
7689 result.is_constant = true;
7690 result.is_meta_type = true;
7691 if (Engine::get_singleton()->has_singleton(p_identifier) || Engine::get_singleton()->has_singleton("_" + p_identifier.operator String())) {
7692 result.is_meta_type = false;
7693 }
7694 result.kind = DataType::NATIVE;
7695 result.native_type = p_identifier;
7696 return result;
7697 }
7698
7699 ClassNode *outer_class = current_class;
7700 while (outer_class) {
7701 if (outer_class->name == p_identifier) {
7702 DataType result;
7703 result.has_type = true;
7704 result.is_constant = true;
7705 result.is_meta_type = true;
7706 result.kind = DataType::CLASS;
7707 result.class_type = outer_class;
7708 return result;
7709 }
7710 if (outer_class->constant_expressions.has(p_identifier)) {
7711 return outer_class->constant_expressions[p_identifier].type;
7712 }
7713 for (int i = 0; i < outer_class->subclasses.size(); i++) {
7714 if (outer_class->subclasses[i] == current_class) {
7715 continue;
7716 }
7717 if (outer_class->subclasses[i]->name == p_identifier) {
7718 DataType result;
7719 result.has_type = true;
7720 result.is_constant = true;
7721 result.is_meta_type = true;
7722 result.kind = DataType::CLASS;
7723 result.class_type = outer_class->subclasses[i];
7724 return result;
7725 }
7726 }
7727 outer_class = outer_class->owner;
7728 }
7729
7730 if (ScriptServer::is_global_class(p_identifier)) {
7731 Ref<Script> scr = ResourceLoader::load(ScriptServer::get_global_class_path(p_identifier));
7732 if (scr.is_valid()) {
7733 DataType result;
7734 result.has_type = true;
7735 result.script_type = scr;
7736 result.is_constant = true;
7737 result.is_meta_type = true;
7738 Ref<GDScript> gds = scr;
7739 if (gds.is_valid()) {
7740 if (!gds->is_valid()) {
7741 _set_error("The class \"" + p_identifier + "\" couldn't be fully loaded (script error or cyclic dependency).");
7742 return DataType();
7743 }
7744 result.kind = DataType::GDSCRIPT;
7745 } else {
7746 result.kind = DataType::SCRIPT;
7747 }
7748 return result;
7749 }
7750 _set_error("The class \"" + p_identifier + "\" was found in global scope, but its script couldn't be loaded.");
7751 return DataType();
7752 }
7753
7754 if (GDScriptLanguage::get_singleton()->get_global_map().has(p_identifier)) {
7755 int idx = GDScriptLanguage::get_singleton()->get_global_map()[p_identifier];
7756 Variant g = GDScriptLanguage::get_singleton()->get_global_array()[idx];
7757 return _type_from_variant(g);
7758 }
7759
7760 if (GDScriptLanguage::get_singleton()->get_named_globals_map().has(p_identifier)) {
7761 Variant g = GDScriptLanguage::get_singleton()->get_named_globals_map()[p_identifier];
7762 return _type_from_variant(g);
7763 }
7764
7765 // Non-tool singletons aren't loaded, check project settings
7766 List<PropertyInfo> props;
7767 ProjectSettings::get_singleton()->get_property_list(&props);
7768
7769 for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) {
7770 String s = E->get().name;
7771 if (!s.begins_with("autoload/")) {
7772 continue;
7773 }
7774 String name = s.get_slice("/", 1);
7775 if (name == p_identifier) {
7776 String script = ProjectSettings::get_singleton()->get(s);
7777 if (script.begins_with("*")) {
7778 script = script.right(1);
7779 }
7780 if (!script.begins_with("res://")) {
7781 script = "res://" + script;
7782 }
7783 Ref<Script> singleton = ResourceLoader::load(script);
7784 if (singleton.is_valid()) {
7785 DataType result;
7786 result.has_type = true;
7787 result.is_constant = true;
7788 result.script_type = singleton;
7789
7790 Ref<GDScript> gds = singleton;
7791 if (gds.is_valid()) {
7792 if (!gds->is_valid()) {
7793 _set_error("Couldn't fully load the singleton script \"" + p_identifier + "\" (possible cyclic reference or parse error).", p_line);
7794 return DataType();
7795 }
7796 result.kind = DataType::GDSCRIPT;
7797 } else {
7798 result.kind = DataType::SCRIPT;
7799 }
7800 }
7801 }
7802 }
7803
7804 // This means looking in the current class, which type is always known
7805 _set_error("The identifier \"" + p_identifier.operator String() + "\" isn't declared in the current scope.", p_line);
7806 }
7807
7808 #ifdef DEBUG_ENABLED
7809 {
7810 DataType tmp_type;
7811 List<DataType> arg_types;
7812 int argcount;
7813 bool _static;
7814 bool vararg;
7815 if (_get_function_signature(base_type, p_identifier, tmp_type, arg_types, argcount, _static, vararg)) {
7816 _add_warning(GDScriptWarning::FUNCTION_USED_AS_PROPERTY, p_line, p_identifier.operator String(), base_type.to_string());
7817 }
7818 }
7819 #endif // DEBUG_ENABLED
7820
7821 _mark_line_as_unsafe(p_line);
7822 return DataType();
7823 }
7824
7825 void GDScriptParser::_check_class_level_types(ClassNode *p_class) {
7826
7827 // Names of internal object properties that we check to avoid overriding them.
7828 // "__meta__" could also be in here, but since it doesn't really affect object metadata,
7829 // it is okay to override it on script.
7830 StringName script_name = CoreStringNames::get_singleton()->_script;
7831
7832 _mark_line_as_safe(p_class->line);
7833
7834 // Constants
7835 for (Map<StringName, ClassNode::Constant>::Element *E = p_class->constant_expressions.front(); E; E = E->next()) {
7836 ClassNode::Constant &c = E->get();
7837 _mark_line_as_safe(c.expression->line);
7838 DataType cont = _resolve_type(c.type, c.expression->line);
7839 DataType expr = _resolve_type(c.expression->get_datatype(), c.expression->line);
7840
7841 if (check_types && !_is_type_compatible(cont, expr)) {
7842 _set_error("The constant value type (" + expr.to_string() + ") isn't compatible with declared type (" + cont.to_string() + ").",
7843 c.expression->line);
7844 return;
7845 }
7846
7847 expr.is_constant = true;
7848 c.type = expr;
7849 c.expression->set_datatype(expr);
7850
7851 DataType tmp;
7852 const StringName &constant_name = E->key();
7853 if (constant_name == script_name || _get_member_type(p_class->base_type, constant_name, tmp)) {
7854 _set_error("The member \"" + String(constant_name) + "\" already exists in a parent class.", c.expression->line);
7855 return;
7856 }
7857 }
7858
7859 // Function declarations
7860 for (int i = 0; i < p_class->static_functions.size(); i++) {
7861 _check_function_types(p_class->static_functions[i]);
7862 if (error_set) return;
7863 }
7864
7865 for (int i = 0; i < p_class->functions.size(); i++) {
7866 _check_function_types(p_class->functions[i]);
7867 if (error_set) return;
7868 }
7869
7870 // Class variables
7871 for (int i = 0; i < p_class->variables.size(); i++) {
7872 ClassNode::Member &v = p_class->variables.write[i];
7873
7874 DataType tmp;
7875 if (v.identifier == script_name || _get_member_type(p_class->base_type, v.identifier, tmp)) {
7876 _set_error("The member \"" + String(v.identifier) + "\" already exists in a parent class.", v.line);
7877 return;
7878 }
7879
7880 _mark_line_as_safe(v.line);
7881 v.data_type = _resolve_type(v.data_type, v.line);
7882 v.initial_assignment->arguments[0]->set_datatype(v.data_type);
7883
7884 if (v.expression) {
7885 DataType expr_type = _reduce_node_type(v.expression);
7886
7887 if (check_types && !_is_type_compatible(v.data_type, expr_type)) {
7888 // Try supertype test
7889 if (_is_type_compatible(expr_type, v.data_type)) {
7890 _mark_line_as_unsafe(v.line);
7891 } else {
7892 // Try with implicit conversion
7893 if (v.data_type.kind != DataType::BUILTIN || !_is_type_compatible(v.data_type, expr_type, true)) {
7894 _set_error("The assigned expression's type (" + expr_type.to_string() + ") doesn't match the variable's type (" +
7895 v.data_type.to_string() + ").",
7896 v.line);
7897 return;
7898 }
7899
7900 // Replace assignment with implicit conversion
7901 BuiltInFunctionNode *convert = alloc_node<BuiltInFunctionNode>();
7902 convert->line = v.line;
7903 convert->function = GDScriptFunctions::TYPE_CONVERT;
7904
7905 ConstantNode *tgt_type = alloc_node<ConstantNode>();
7906 tgt_type->line = v.line;
7907 tgt_type->value = (int)v.data_type.builtin_type;
7908
7909 OperatorNode *convert_call = alloc_node<OperatorNode>();
7910 convert_call->line = v.line;
7911 convert_call->op = OperatorNode::OP_CALL;
7912 convert_call->arguments.push_back(convert);
7913 convert_call->arguments.push_back(v.expression);
7914 convert_call->arguments.push_back(tgt_type);
7915
7916 v.expression = convert_call;
7917 v.initial_assignment->arguments.write[1] = convert_call;
7918 }
7919 }
7920
7921 if (v.data_type.infer_type) {
7922 if (!expr_type.has_type) {
7923 _set_error("The assigned value doesn't have a set type; the variable type can't be inferred.", v.line);
7924 return;
7925 }
7926 if (expr_type.kind == DataType::BUILTIN && expr_type.builtin_type == Variant::NIL) {
7927 _set_error("The variable type cannot be inferred because its value is \"null\".", v.line);
7928 return;
7929 }
7930 v.data_type = expr_type;
7931 v.data_type.is_constant = false;
7932 }
7933 }
7934
7935 // Check export hint
7936 if (v.data_type.has_type && v._export.type != Variant::NIL) {
7937 DataType export_type = _type_from_property(v._export);
7938 if (!_is_type_compatible(v.data_type, export_type, true)) {
7939 _set_error("The export hint's type (" + export_type.to_string() + ") doesn't match the variable's type (" +
7940 v.data_type.to_string() + ").",
7941 v.line);
7942 return;
7943 }
7944 }
7945
7946 // Setter and getter
7947 if (v.setter == StringName() && v.getter == StringName()) continue;
7948
7949 bool found_getter = false;
7950 bool found_setter = false;
7951 for (int j = 0; j < p_class->functions.size(); j++) {
7952 if (v.setter == p_class->functions[j]->name) {
7953 found_setter = true;
7954 FunctionNode *setter = p_class->functions[j];
7955
7956 if (setter->get_required_argument_count() != 1 &&
7957 !(setter->get_required_argument_count() == 0 && setter->default_values.size() > 0)) {
7958 _set_error("The setter function needs to receive exactly 1 argument. See \"" + setter->name +
7959 "()\" definition at line " + itos(setter->line) + ".",
7960 v.line);
7961 return;
7962 }
7963 if (!_is_type_compatible(v.data_type, setter->argument_types[0])) {
7964 _set_error("The setter argument's type (" + setter->argument_types[0].to_string() +
7965 ") doesn't match the variable's type (" + v.data_type.to_string() + "). See \"" +
7966 setter->name + "()\" definition at line " + itos(setter->line) + ".",
7967 v.line);
7968 return;
7969 }
7970 continue;
7971 }
7972 if (v.getter == p_class->functions[j]->name) {
7973 found_getter = true;
7974 FunctionNode *getter = p_class->functions[j];
7975
7976 if (getter->get_required_argument_count() != 0) {
7977 _set_error("The getter function can't receive arguments. See \"" + getter->name +
7978 "()\" definition at line " + itos(getter->line) + ".",
7979 v.line);
7980 return;
7981 }
7982 if (!_is_type_compatible(v.data_type, getter->get_datatype())) {
7983 _set_error("The getter return type (" + getter->get_datatype().to_string() +
7984 ") doesn't match the variable's type (" + v.data_type.to_string() +
7985 "). See \"" + getter->name + "()\" definition at line " + itos(getter->line) + ".",
7986 v.line);
7987 return;
7988 }
7989 }
7990 if (found_getter && found_setter) break;
7991 }
7992
7993 if ((found_getter || v.getter == StringName()) && (found_setter || v.setter == StringName())) continue;
7994
7995 // Check for static functions
7996 for (int j = 0; j < p_class->static_functions.size(); j++) {
7997 if (v.setter == p_class->static_functions[j]->name) {
7998 FunctionNode *setter = p_class->static_functions[j];
7999 _set_error("The setter can't be a static function. See \"" + setter->name + "()\" definition at line " + itos(setter->line) + ".", v.line);
8000 return;
8001 }
8002 if (v.getter == p_class->static_functions[j]->name) {
8003 FunctionNode *getter = p_class->static_functions[j];
8004 _set_error("The getter can't be a static function. See \"" + getter->name + "()\" definition at line " + itos(getter->line) + ".", v.line);
8005 return;
8006 }
8007 }
8008
8009 if (!found_setter && v.setter != StringName()) {
8010 _set_error("The setter function isn't defined.", v.line);
8011 return;
8012 }
8013
8014 if (!found_getter && v.getter != StringName()) {
8015 _set_error("The getter function isn't defined.", v.line);
8016 return;
8017 }
8018 }
8019
8020 // Signals
8021 DataType base = p_class->base_type;
8022
8023 while (base.kind == DataType::CLASS) {
8024 ClassNode *base_class = base.class_type;
8025 for (int i = 0; i < p_class->_signals.size(); i++) {
8026 for (int j = 0; j < base_class->_signals.size(); j++) {
8027 if (p_class->_signals[i].name == base_class->_signals[j].name) {
8028 _set_error("The signal \"" + p_class->_signals[i].name + "\" already exists in a parent class.", p_class->_signals[i].line);
8029 return;
8030 }
8031 }
8032 }
8033 base = base_class->base_type;
8034 }
8035
8036 StringName native;
8037 if (base.kind == DataType::GDSCRIPT || base.kind == DataType::SCRIPT) {
8038 Ref<Script> scr = base.script_type;
8039 if (scr.is_valid() && scr->is_valid()) {
8040 native = scr->get_instance_base_type();
8041 for (int i = 0; i < p_class->_signals.size(); i++) {
8042 if (scr->has_script_signal(p_class->_signals[i].name)) {
8043 _set_error("The signal \"" + p_class->_signals[i].name + "\" already exists in a parent class.", p_class->_signals[i].line);
8044 return;
8045 }
8046 }
8047 }
8048 } else if (base.kind == DataType::NATIVE) {
8049 native = base.native_type;
8050 }
8051
8052 if (native != StringName()) {
8053 for (int i = 0; i < p_class->_signals.size(); i++) {
8054 if (ClassDB::has_signal(native, p_class->_signals[i].name)) {
8055 _set_error("The signal \"" + p_class->_signals[i].name + "\" already exists in a parent class.", p_class->_signals[i].line);
8056 return;
8057 }
8058 }
8059 }
8060
8061 // Inner classes
8062 for (int i = 0; i < p_class->subclasses.size(); i++) {
8063 current_class = p_class->subclasses[i];
8064 _check_class_level_types(current_class);
8065 if (error_set) return;
8066 current_class = p_class;
8067 }
8068 }
8069
8070 void GDScriptParser::_check_function_types(FunctionNode *p_function) {
8071
8072 p_function->return_type = _resolve_type(p_function->return_type, p_function->line);
8073
8074 // Arguments
8075 int defaults_ofs = p_function->arguments.size() - p_function->default_values.size();
8076 for (int i = 0; i < p_function->arguments.size(); i++) {
8077 if (i < defaults_ofs) {
8078 p_function->argument_types.write[i] = _resolve_type(p_function->argument_types[i], p_function->line);
8079 } else {
8080 if (p_function->default_values[i - defaults_ofs]->type != Node::TYPE_OPERATOR) {
8081 _set_error("Parser bug: invalid argument default value.", p_function->line, p_function->column);
8082 return;
8083 }
8084
8085 OperatorNode *op = static_cast<OperatorNode *>(p_function->default_values[i - defaults_ofs]);
8086
8087 if (op->op != OperatorNode::OP_ASSIGN || op->arguments.size() != 2) {
8088 _set_error("Parser bug: invalid argument default value operation.", p_function->line);
8089 return;
8090 }
8091
8092 DataType def_type = _reduce_node_type(op->arguments[1]);
8093
8094 if (p_function->argument_types[i].infer_type) {
8095 def_type.is_constant = false;
8096 p_function->argument_types.write[i] = def_type;
8097 } else {
8098 p_function->argument_types.write[i] = _resolve_type(p_function->argument_types[i], p_function->line);
8099
8100 if (!_is_type_compatible(p_function->argument_types[i], def_type, true)) {
8101 String arg_name = p_function->arguments[i];
8102 _set_error("Value type (" + def_type.to_string() + ") doesn't match the type of argument '" +
8103 arg_name + "' (" + p_function->argument_types[i].to_string() + ").",
8104 p_function->line);
8105 }
8106 }
8107 }
8108 #ifdef DEBUG_ENABLED
8109 if (p_function->arguments_usage[i] == 0 && !p_function->arguments[i].operator String().begins_with("_")) {
8110 _add_warning(GDScriptWarning::UNUSED_ARGUMENT, p_function->line, p_function->name, p_function->arguments[i].operator String());
8111 }
8112 for (int j = 0; j < current_class->variables.size(); j++) {
8113 if (current_class->variables[j].identifier == p_function->arguments[i]) {
8114 _add_warning(GDScriptWarning::SHADOWED_VARIABLE, p_function->line, p_function->arguments[i], itos(current_class->variables[j].line));
8115 }
8116 }
8117 #endif // DEBUG_ENABLED
8118 }
8119
8120 if (!(p_function->name == "_init")) {
8121 // Signature for the initializer may vary
8122 #ifdef DEBUG_ENABLED
8123 DataType return_type;
8124 List<DataType> arg_types;
8125 int default_arg_count = 0;
8126 bool _static = false;
8127 bool vararg = false;
8128
8129 DataType base_type = current_class->base_type;
8130 if (_get_function_signature(base_type, p_function->name, return_type, arg_types, default_arg_count, _static, vararg)) {
8131 bool valid = _static == p_function->_static;
8132 valid = valid && return_type == p_function->return_type;
8133 int argsize_diff = p_function->arguments.size() - arg_types.size();
8134 valid = valid && argsize_diff >= 0;
8135 valid = valid && p_function->default_values.size() >= default_arg_count + argsize_diff;
8136 int i = 0;
8137 for (List<DataType>::Element *E = arg_types.front(); valid && E; E = E->next()) {
8138 valid = valid && E->get() == p_function->argument_types[i++];
8139 }
8140
8141 if (!valid) {
8142 String parent_signature = return_type.has_type ? return_type.to_string() : "Variant";
8143 if (parent_signature == "null") {
8144 parent_signature = "void";
8145 }
8146 parent_signature += " " + p_function->name + "(";
8147 if (arg_types.size()) {
8148 int j = 0;
8149 for (List<DataType>::Element *E = arg_types.front(); E; E = E->next()) {
8150 if (E != arg_types.front()) {
8151 parent_signature += ", ";
8152 }
8153 String arg = E->get().to_string();
8154 if (arg == "null" || arg == "var") {
8155 arg = "Variant";
8156 }
8157 parent_signature += arg;
8158 if (j == arg_types.size() - default_arg_count) {
8159 parent_signature += "=default";
8160 }
8161
8162 j++;
8163 }
8164 }
8165 parent_signature += ")";
8166 _set_error("The function signature doesn't match the parent. Parent signature is: \"" + parent_signature + "\".", p_function->line);
8167 return;
8168 }
8169 }
8170 #endif // DEBUG_ENABLED
8171 } else {
8172 if (p_function->return_type.has_type && (p_function->return_type.kind != DataType::BUILTIN || p_function->return_type.builtin_type != Variant::NIL)) {
8173 _set_error("The constructor can't return a value.", p_function->line);
8174 return;
8175 }
8176 }
8177
8178 if (p_function->return_type.has_type && (p_function->return_type.kind != DataType::BUILTIN || p_function->return_type.builtin_type != Variant::NIL)) {
8179 if (!p_function->body->has_return) {
8180 _set_error("A non-void function must return a value in all possible paths.", p_function->line);
8181 return;
8182 }
8183 }
8184
8185 if (p_function->has_yield) {
8186 // yield() will make the function return a GDScriptFunctionState, so the type is ambiguous
8187 p_function->return_type.has_type = false;
8188 p_function->return_type.may_yield = true;
8189 }
8190 }
8191
8192 void GDScriptParser::_check_class_blocks_types(ClassNode *p_class) {
8193
8194 // Function blocks
8195 for (int i = 0; i < p_class->static_functions.size(); i++) {
8196 current_function = p_class->static_functions[i];
8197 current_block = current_function->body;
8198 _mark_line_as_safe(current_function->line);
8199 _check_block_types(current_block);
8200 current_block = NULL;
8201 current_function = NULL;
8202 if (error_set) return;
8203 }
8204
8205 for (int i = 0; i < p_class->functions.size(); i++) {
8206 current_function = p_class->functions[i];
8207 current_block = current_function->body;
8208 _mark_line_as_safe(current_function->line);
8209 _check_block_types(current_block);
8210 current_block = NULL;
8211 current_function = NULL;
8212 if (error_set) return;
8213 }
8214
8215 #ifdef DEBUG_ENABLED
8216 // Warnings
8217 for (int i = 0; i < p_class->variables.size(); i++) {
8218 if (p_class->variables[i].usages == 0) {
8219 _add_warning(GDScriptWarning::UNUSED_CLASS_VARIABLE, p_class->variables[i].line, p_class->variables[i].identifier);
8220 }
8221 }
8222 for (int i = 0; i < p_class->_signals.size(); i++) {
8223 if (p_class->_signals[i].emissions == 0) {
8224 _add_warning(GDScriptWarning::UNUSED_SIGNAL, p_class->_signals[i].line, p_class->_signals[i].name);
8225 }
8226 }
8227 #endif // DEBUG_ENABLED
8228
8229 // Inner classes
8230 for (int i = 0; i < p_class->subclasses.size(); i++) {
8231 current_class = p_class->subclasses[i];
8232 _check_class_blocks_types(current_class);
8233 if (error_set) return;
8234 current_class = p_class;
8235 }
8236 }
8237
8238 #ifdef DEBUG_ENABLED
8239 static String _find_function_name(const GDScriptParser::OperatorNode *p_call) {
8240 switch (p_call->arguments[0]->type) {
8241 case GDScriptParser::Node::TYPE_TYPE: {
8242 return Variant::get_type_name(static_cast<GDScriptParser::TypeNode *>(p_call->arguments[0])->vtype);
8243 } break;
8244 case GDScriptParser::Node::TYPE_BUILT_IN_FUNCTION: {
8245 return GDScriptFunctions::get_func_name(static_cast<GDScriptParser::BuiltInFunctionNode *>(p_call->arguments[0])->function);
8246 } break;
8247 default: {
8248 int id_index = p_call->op == GDScriptParser::OperatorNode::OP_PARENT_CALL ? 0 : 1;
8249 if (p_call->arguments.size() > id_index && p_call->arguments[id_index]->type == GDScriptParser::Node::TYPE_IDENTIFIER) {
8250 return static_cast<GDScriptParser::IdentifierNode *>(p_call->arguments[id_index])->name;
8251 }
8252 } break;
8253 }
8254 return String();
8255 }
8256 #endif // DEBUG_ENABLED
8257
8258 void GDScriptParser::_check_block_types(BlockNode *p_block) {
8259
8260 Node *last_var_assign = NULL;
8261
8262 // Check each statement
8263 for (List<Node *>::Element *E = p_block->statements.front(); E; E = E->next()) {
8264 Node *statement = E->get();
8265 switch (statement->type) {
8266 case Node::TYPE_NEWLINE:
8267 case Node::TYPE_BREAKPOINT: {
8268 // Nothing to do
8269 } break;
8270 case Node::TYPE_ASSERT: {
8271 AssertNode *an = static_cast<AssertNode *>(statement);
8272 _mark_line_as_safe(an->line);
8273 _reduce_node_type(an->condition);
8274 _reduce_node_type(an->message);
8275 } break;
8276 case Node::TYPE_LOCAL_VAR: {
8277 LocalVarNode *lv = static_cast<LocalVarNode *>(statement);
8278 lv->datatype = _resolve_type(lv->datatype, lv->line);
8279 _mark_line_as_safe(lv->line);
8280
8281 last_var_assign = lv->assign;
8282 if (lv->assign) {
8283 lv->assign_op->arguments[0]->set_datatype(lv->datatype);
8284 DataType assign_type = _reduce_node_type(lv->assign);
8285 #ifdef DEBUG_ENABLED
8286 if (assign_type.has_type && assign_type.kind == DataType::BUILTIN && assign_type.builtin_type == Variant::NIL) {
8287 if (lv->assign->type == Node::TYPE_OPERATOR) {
8288 OperatorNode *call = static_cast<OperatorNode *>(lv->assign);
8289 if (call->op == OperatorNode::OP_CALL || call->op == OperatorNode::OP_PARENT_CALL) {
8290 _add_warning(GDScriptWarning::VOID_ASSIGNMENT, lv->line, _find_function_name(call));
8291 }
8292 }
8293 }
8294 if (lv->datatype.has_type && assign_type.may_yield && lv->assign->type == Node::TYPE_OPERATOR) {
8295 _add_warning(GDScriptWarning::FUNCTION_MAY_YIELD, lv->line, _find_function_name(static_cast<OperatorNode *>(lv->assign)));
8296 }
8297 for (int i = 0; i < current_class->variables.size(); i++) {
8298 if (current_class->variables[i].identifier == lv->name) {
8299 _add_warning(GDScriptWarning::SHADOWED_VARIABLE, lv->line, lv->name, itos(current_class->variables[i].line));
8300 }
8301 }
8302 #endif // DEBUG_ENABLED
8303
8304 if (!_is_type_compatible(lv->datatype, assign_type)) {
8305 // Try supertype test
8306 if (_is_type_compatible(assign_type, lv->datatype)) {
8307 _mark_line_as_unsafe(lv->line);
8308 } else {
8309 // Try implicit conversion
8310 if (lv->datatype.kind != DataType::BUILTIN || !_is_type_compatible(lv->datatype, assign_type, true)) {
8311 _set_error("The assigned value type (" + assign_type.to_string() + ") doesn't match the variable's type (" +
8312 lv->datatype.to_string() + ").",
8313 lv->line);
8314 return;
8315 }
8316 // Replace assignment with implicit conversion
8317 BuiltInFunctionNode *convert = alloc_node<BuiltInFunctionNode>();
8318 convert->line = lv->line;
8319 convert->function = GDScriptFunctions::TYPE_CONVERT;
8320
8321 ConstantNode *tgt_type = alloc_node<ConstantNode>();
8322 tgt_type->line = lv->line;
8323 tgt_type->value = (int)lv->datatype.builtin_type;
8324
8325 OperatorNode *convert_call = alloc_node<OperatorNode>();
8326 convert_call->line = lv->line;
8327 convert_call->op = OperatorNode::OP_CALL;
8328 convert_call->arguments.push_back(convert);
8329 convert_call->arguments.push_back(lv->assign);
8330 convert_call->arguments.push_back(tgt_type);
8331
8332 lv->assign = convert_call;
8333 lv->assign_op->arguments.write[1] = convert_call;
8334 #ifdef DEBUG_ENABLED
8335 if (lv->datatype.builtin_type == Variant::INT && assign_type.builtin_type == Variant::REAL) {
8336 _add_warning(GDScriptWarning::NARROWING_CONVERSION, lv->line);
8337 }
8338 #endif // DEBUG_ENABLED
8339 }
8340 }
8341 if (lv->datatype.infer_type) {
8342 if (!assign_type.has_type) {
8343 _set_error("The assigned value doesn't have a set type; the variable type can't be inferred.", lv->line);
8344 return;
8345 }
8346 if (assign_type.kind == DataType::BUILTIN && assign_type.builtin_type == Variant::NIL) {
8347 _set_error("The variable type cannot be inferred because its value is \"null\".", lv->line);
8348 return;
8349 }
8350 lv->datatype = assign_type;
8351 lv->datatype.is_constant = false;
8352 }
8353 if (lv->datatype.has_type && !assign_type.has_type) {
8354 _mark_line_as_unsafe(lv->line);
8355 }
8356 }
8357 } break;
8358 case Node::TYPE_OPERATOR: {
8359 OperatorNode *op = static_cast<OperatorNode *>(statement);
8360
8361 switch (op->op) {
8362 case OperatorNode::OP_ASSIGN:
8363 case OperatorNode::OP_ASSIGN_ADD:
8364 case OperatorNode::OP_ASSIGN_SUB:
8365 case OperatorNode::OP_ASSIGN_MUL:
8366 case OperatorNode::OP_ASSIGN_DIV:
8367 case OperatorNode::OP_ASSIGN_MOD:
8368 case OperatorNode::OP_ASSIGN_SHIFT_LEFT:
8369 case OperatorNode::OP_ASSIGN_SHIFT_RIGHT:
8370 case OperatorNode::OP_ASSIGN_BIT_AND:
8371 case OperatorNode::OP_ASSIGN_BIT_OR:
8372 case OperatorNode::OP_ASSIGN_BIT_XOR: {
8373 if (op->arguments.size() < 2) {
8374 _set_error("Parser bug: operation without enough arguments.", op->line, op->column);
8375 return;
8376 }
8377
8378 if (op->arguments[1] == last_var_assign) {
8379 // Assignment was already checked
8380 break;
8381 }
8382
8383 _mark_line_as_safe(op->line);
8384
8385 DataType lh_type = _reduce_node_type(op->arguments[0]);
8386
8387 if (error_set) {
8388 return;
8389 }
8390
8391 if (check_types) {
8392 if (!lh_type.has_type) {
8393 if (op->arguments[0]->type == Node::TYPE_OPERATOR) {
8394 _mark_line_as_unsafe(op->line);
8395 }
8396 }
8397 if (lh_type.is_constant) {
8398 _set_error("Can't assign a new value to a constant.", op->line);
8399 return;
8400 }
8401 }
8402
8403 DataType rh_type;
8404 if (op->op != OperatorNode::OP_ASSIGN) {
8405 // Validate operation
8406 DataType arg_type = _reduce_node_type(op->arguments[1]);
8407 if (!arg_type.has_type) {
8408 _mark_line_as_unsafe(op->line);
8409 break;
8410 }
8411
8412 Variant::Operator oper = _get_variant_operation(op->op);
8413 bool valid = false;
8414 rh_type = _get_operation_type(oper, lh_type, arg_type, valid);
8415
8416 if (check_types && !valid) {
8417 _set_error("Invalid operand types (\"" + lh_type.to_string() + "\" and \"" + arg_type.to_string() +
8418 "\") to assignment operator \"" + Variant::get_operator_name(oper) + "\".",
8419 op->line);
8420 return;
8421 }
8422 } else {
8423 rh_type = _reduce_node_type(op->arguments[1]);
8424 }
8425 #ifdef DEBUG_ENABLED
8426 if (rh_type.has_type && rh_type.kind == DataType::BUILTIN && rh_type.builtin_type == Variant::NIL) {
8427 if (op->arguments[1]->type == Node::TYPE_OPERATOR) {
8428 OperatorNode *call = static_cast<OperatorNode *>(op->arguments[1]);
8429 if (call->op == OperatorNode::OP_CALL || call->op == OperatorNode::OP_PARENT_CALL) {
8430 _add_warning(GDScriptWarning::VOID_ASSIGNMENT, op->line, _find_function_name(call));
8431 }
8432 }
8433 }
8434 if (lh_type.has_type && rh_type.may_yield && op->arguments[1]->type == Node::TYPE_OPERATOR) {
8435 _add_warning(GDScriptWarning::FUNCTION_MAY_YIELD, op->line, _find_function_name(static_cast<OperatorNode *>(op->arguments[1])));
8436 }
8437
8438 #endif // DEBUG_ENABLED
8439 bool type_match = lh_type.has_type && rh_type.has_type;
8440 if (check_types && !_is_type_compatible(lh_type, rh_type)) {
8441 type_match = false;
8442
8443 // Try supertype test
8444 if (_is_type_compatible(rh_type, lh_type)) {
8445 _mark_line_as_unsafe(op->line);
8446 } else {
8447 // Try implicit conversion
8448 if (lh_type.kind != DataType::BUILTIN || !_is_type_compatible(lh_type, rh_type, true)) {
8449 _set_error("The assigned value's type (" + rh_type.to_string() + ") doesn't match the variable's type (" +
8450 lh_type.to_string() + ").",
8451 op->line);
8452 return;
8453 }
8454 if (op->op == OperatorNode::OP_ASSIGN) {
8455 // Replace assignment with implicit conversion
8456 BuiltInFunctionNode *convert = alloc_node<BuiltInFunctionNode>();
8457 convert->line = op->line;
8458 convert->function = GDScriptFunctions::TYPE_CONVERT;
8459
8460 ConstantNode *tgt_type = alloc_node<ConstantNode>();
8461 tgt_type->line = op->line;
8462 tgt_type->value = (int)lh_type.builtin_type;
8463
8464 OperatorNode *convert_call = alloc_node<OperatorNode>();
8465 convert_call->line = op->line;
8466 convert_call->op = OperatorNode::OP_CALL;
8467 convert_call->arguments.push_back(convert);
8468 convert_call->arguments.push_back(op->arguments[1]);
8469 convert_call->arguments.push_back(tgt_type);
8470
8471 op->arguments.write[1] = convert_call;
8472
8473 type_match = true; // Since we are converting, the type is matching
8474 }
8475 #ifdef DEBUG_ENABLED
8476 if (lh_type.builtin_type == Variant::INT && rh_type.builtin_type == Variant::REAL) {
8477 _add_warning(GDScriptWarning::NARROWING_CONVERSION, op->line);
8478 }
8479 #endif // DEBUG_ENABLED
8480 }
8481 }
8482 #ifdef DEBUG_ENABLED
8483 if (!rh_type.has_type && (op->op != OperatorNode::OP_ASSIGN || lh_type.has_type || op->arguments[0]->type == Node::TYPE_OPERATOR)) {
8484 _mark_line_as_unsafe(op->line);
8485 }
8486 #endif // DEBUG_ENABLED
8487 op->datatype.has_type = type_match;
8488 } break;
8489 case OperatorNode::OP_CALL:
8490 case OperatorNode::OP_PARENT_CALL: {
8491 _mark_line_as_safe(op->line);
8492 DataType func_type = _reduce_function_call_type(op);
8493 #ifdef DEBUG_ENABLED
8494 if (func_type.has_type && (func_type.kind != DataType::BUILTIN || func_type.builtin_type != Variant::NIL)) {
8495 // Figure out function name for warning
8496 String func_name = _find_function_name(op);
8497 if (func_name.empty()) {
8498 func_name = "<undetected name>";
8499 }
8500 _add_warning(GDScriptWarning::RETURN_VALUE_DISCARDED, op->line, func_name);
8501 }
8502 #endif // DEBUG_ENABLED
8503 if (error_set) return;
8504 } break;
8505 case OperatorNode::OP_YIELD: {
8506 _mark_line_as_safe(op->line);
8507 _reduce_node_type(op);
8508 } break;
8509 default: {
8510 _mark_line_as_safe(op->line);
8511 _reduce_node_type(op); // Test for safety anyway
8512 #ifdef DEBUG_ENABLED
8513 if (op->op == OperatorNode::OP_TERNARY_IF) {
8514 _add_warning(GDScriptWarning::STANDALONE_TERNARY, statement->line);
8515 } else {
8516 _add_warning(GDScriptWarning::STANDALONE_EXPRESSION, statement->line);
8517 }
8518 #endif // DEBUG_ENABLED
8519 }
8520 }
8521 } break;
8522 case Node::TYPE_CONTROL_FLOW: {
8523 ControlFlowNode *cf = static_cast<ControlFlowNode *>(statement);
8524 _mark_line_as_safe(cf->line);
8525
8526 switch (cf->cf_type) {
8527 case ControlFlowNode::CF_RETURN: {
8528 DataType function_type = current_function->get_datatype();
8529
8530 DataType ret_type;
8531 if (cf->arguments.size() > 0) {
8532 ret_type = _reduce_node_type(cf->arguments[0]);
8533 if (error_set) {
8534 return;
8535 }
8536 }
8537
8538 if (!function_type.has_type) break;
8539
8540 if (function_type.kind == DataType::BUILTIN && function_type.builtin_type == Variant::NIL) {
8541 // Return void, should not have arguments
8542 if (cf->arguments.size() > 0) {
8543 _set_error("A void function cannot return a value.", cf->line, cf->column);
8544 return;
8545 }
8546 } else {
8547 // Return something, cannot be empty
8548 if (cf->arguments.size() == 0) {
8549 _set_error("A non-void function must return a value.", cf->line, cf->column);
8550 return;
8551 }
8552
8553 if (!_is_type_compatible(function_type, ret_type)) {
8554 _set_error("The returned value type (" + ret_type.to_string() + ") doesn't match the function return type (" +
8555 function_type.to_string() + ").",
8556 cf->line, cf->column);
8557 return;
8558 }
8559 }
8560 } break;
8561 case ControlFlowNode::CF_MATCH: {
8562 MatchNode *match_node = cf->match;
8563 _transform_match_statment(match_node);
8564 } break;
8565 default: {
8566 if (cf->body_else) {
8567 _mark_line_as_safe(cf->body_else->line);
8568 }
8569 for (int i = 0; i < cf->arguments.size(); i++) {
8570 _reduce_node_type(cf->arguments[i]);
8571 }
8572 } break;
8573 }
8574 } break;
8575 case Node::TYPE_CONSTANT: {
8576 ConstantNode *cn = static_cast<ConstantNode *>(statement);
8577 // Strings are fine since they can be multiline comments
8578 if (cn->value.get_type() == Variant::STRING) {
8579 break;
8580 }
8581 FALLTHROUGH;
8582 }
8583 default: {
8584 _mark_line_as_safe(statement->line);
8585 _reduce_node_type(statement); // Test for safety anyway
8586 #ifdef DEBUG_ENABLED
8587 _add_warning(GDScriptWarning::STANDALONE_EXPRESSION, statement->line);
8588 #endif // DEBUG_ENABLED
8589 }
8590 }
8591 }
8592
8593 // Parse sub blocks
8594 for (int i = 0; i < p_block->sub_blocks.size(); i++) {
8595 current_block = p_block->sub_blocks[i];
8596 _check_block_types(current_block);
8597 current_block = p_block;
8598 if (error_set) return;
8599 }
8600
8601 #ifdef DEBUG_ENABLED
8602 // Warnings check
8603 for (Map<StringName, LocalVarNode *>::Element *E = p_block->variables.front(); E; E = E->next()) {
8604 LocalVarNode *lv = E->get();
8605 if (!lv->name.operator String().begins_with("_")) {
8606 if (lv->usages == 0) {
8607 _add_warning(GDScriptWarning::UNUSED_VARIABLE, lv->line, lv->name);
8608 } else if (lv->assignments == 0) {
8609 _add_warning(GDScriptWarning::UNASSIGNED_VARIABLE, lv->line, lv->name);
8610 }
8611 }
8612 }
8613 #endif // DEBUG_ENABLED
8614 }
8615
8616 void GDScriptParser::_set_error(const String &p_error, int p_line, int p_column) {
8617
8618 if (error_set)
8619 return; //allow no further errors
8620
8621 error = p_error;
8622 error_line = p_line < 0 ? tokenizer->get_token_line() : p_line;
8623 error_column = p_column < 0 ? tokenizer->get_token_column() : p_column;
8624 error_set = true;
8625 }
8626
8627 #ifdef DEBUG_ENABLED
8628 void GDScriptParser::_add_warning(int p_code, int p_line, const String &p_symbol1, const String &p_symbol2, const String &p_symbol3, const String &p_symbol4) {
8629 Vector<String> symbols;
8630 if (!p_symbol1.empty()) {
8631 symbols.push_back(p_symbol1);
8632 }
8633 if (!p_symbol2.empty()) {
8634 symbols.push_back(p_symbol2);
8635 }
8636 if (!p_symbol3.empty()) {
8637 symbols.push_back(p_symbol3);
8638 }
8639 if (!p_symbol4.empty()) {
8640 symbols.push_back(p_symbol4);
8641 }
8642 _add_warning(p_code, p_line, symbols);
8643 }
8644
8645 void GDScriptParser::_add_warning(int p_code, int p_line, const Vector<String> &p_symbols) {
8646 if (GLOBAL_GET("debug/gdscript/warnings/exclude_addons").booleanize() && base_path.begins_with("res://addons/")) {
8647 return;
8648 }
8649 if (tokenizer->is_ignoring_warnings() || !GLOBAL_GET("debug/gdscript/warnings/enable").booleanize()) {
8650 return;
8651 }
8652 String warn_name = GDScriptWarning::get_name_from_code((GDScriptWarning::Code)p_code).to_lower();
8653 if (tokenizer->get_warning_global_skips().has(warn_name)) {
8654 return;
8655 }
8656 if (!GLOBAL_GET("debug/gdscript/warnings/" + warn_name)) {
8657 return;
8658 }
8659
8660 GDScriptWarning warn;
8661 warn.code = (GDScriptWarning::Code)p_code;
8662 warn.symbols = p_symbols;
8663 warn.line = p_line == -1 ? tokenizer->get_token_line() : p_line;
8664
8665 List<GDScriptWarning>::Element *before = NULL;
8666 for (List<GDScriptWarning>::Element *E = warnings.front(); E; E = E->next()) {
8667 if (E->get().line > warn.line) {
8668 break;
8669 }
8670 before = E;
8671 }
8672 if (before) {
8673 warnings.insert_after(before, warn);
8674 } else {
8675 warnings.push_front(warn);
8676 }
8677 }
8678 #endif // DEBUG_ENABLED
8679
8680 String GDScriptParser::get_error() const {
8681
8682 return error;
8683 }
8684
8685 int GDScriptParser::get_error_line() const {
8686
8687 return error_line;
8688 }
8689 int GDScriptParser::get_error_column() const {
8690
8691 return error_column;
8692 }
8693
8694 bool GDScriptParser::has_error() const {
8695 return error_set;
8696 }
8697
8698 Error GDScriptParser::_parse(const String &p_base_path) {
8699
8700 base_path = p_base_path;
8701
8702 //assume class
8703 ClassNode *main_class = alloc_node<ClassNode>();
8704 main_class->initializer = alloc_node<BlockNode>();
8705 main_class->initializer->parent_class = main_class;
8706 main_class->ready = alloc_node<BlockNode>();
8707 main_class->ready->parent_class = main_class;
8708 current_class = main_class;
8709
8710 _parse_class(main_class);
8711
8712 if (tokenizer->get_token() == GDScriptTokenizer::TK_ERROR) {
8713 error_set = false;
8714 _set_error("Parse error: " + tokenizer->get_token_error());
8715 }
8716
8717 bool for_completion_error_set = false;
8718 if (error_set && for_completion) {
8719 for_completion_error_set = true;
8720 error_set = false;
8721 }
8722
8723 if (error_set) {
8724 return ERR_PARSE_ERROR;
8725 }
8726
8727 if (dependencies_only) {
8728 return OK;
8729 }
8730
8731 _determine_inheritance(main_class);
8732
8733 if (error_set) {
8734 return ERR_PARSE_ERROR;
8735 }
8736
8737 current_class = main_class;
8738 current_function = NULL;
8739 current_block = NULL;
8740
8741 if (for_completion) check_types = false;
8742
8743 // Resolve all class-level stuff before getting into function blocks
8744 _check_class_level_types(main_class);
8745
8746 if (error_set) {
8747 return ERR_PARSE_ERROR;
8748 }
8749
8750 // Resolve the function blocks
8751 _check_class_blocks_types(main_class);
8752
8753 if (for_completion_error_set) {
8754 error_set = true;
8755 }
8756
8757 if (error_set) {
8758 return ERR_PARSE_ERROR;
8759 }
8760
8761 #ifdef DEBUG_ENABLED
8762
8763 // Resolve warning ignores
8764 Vector<Pair<int, String> > warning_skips = tokenizer->get_warning_skips();
8765 bool warning_is_error = GLOBAL_GET("debug/gdscript/warnings/treat_warnings_as_errors").booleanize();
8766 for (List<GDScriptWarning>::Element *E = warnings.front(); E;) {
8767 GDScriptWarning &w = E->get();
8768 int skip_index = -1;
8769 for (int i = 0; i < warning_skips.size(); i++) {
8770 if (warning_skips[i].first >= w.line) {
8771 break;
8772 }
8773 skip_index = i;
8774 }
8775 List<GDScriptWarning>::Element *next = E->next();
8776 bool erase = false;
8777 if (skip_index != -1) {
8778 if (warning_skips[skip_index].second == GDScriptWarning::get_name_from_code(w.code).to_lower()) {
8779 erase = true;
8780 }
8781 warning_skips.remove(skip_index);
8782 }
8783 if (erase) {
8784 warnings.erase(E);
8785 } else if (warning_is_error) {
8786 _set_error(w.get_message() + " (warning treated as error)", w.line);
8787 return ERR_PARSE_ERROR;
8788 }
8789 E = next;
8790 }
8791 #endif // DEBUG_ENABLED
8792
8793 return OK;
8794 }
8795
8796 Error GDScriptParser::parse_bytecode(const Vector<uint8_t> &p_bytecode, const String &p_base_path, const String &p_self_path) {
8797
8798 clear();
8799
8800 self_path = p_self_path;
8801 GDScriptTokenizerBuffer *tb = memnew(GDScriptTokenizerBuffer);
8802 tb->set_code_buffer(p_bytecode);
8803 tokenizer = tb;
8804 Error ret = _parse(p_base_path);
8805 memdelete(tb);
8806 tokenizer = NULL;
8807 return ret;
8808 }
8809
8810 Error GDScriptParser::parse(const String &p_code, const String &p_base_path, bool p_just_validate, const String &p_self_path, bool p_for_completion, Set<int> *r_safe_lines, bool p_dependencies_only) {
8811
8812 clear();
8813
8814 self_path = p_self_path;
8815 GDScriptTokenizerText *tt = memnew(GDScriptTokenizerText);
8816 tt->set_code(p_code);
8817
8818 validating = p_just_validate;
8819 for_completion = p_for_completion;
8820 dependencies_only = p_dependencies_only;
8821 #ifdef DEBUG_ENABLED
8822 safe_lines = r_safe_lines;
8823 #endif // DEBUG_ENABLED
8824 tokenizer = tt;
8825 Error ret = _parse(p_base_path);
8826 memdelete(tt);
8827 tokenizer = NULL;
8828 return ret;
8829 }
8830
8831 bool GDScriptParser::is_tool_script() const {
8832
8833 return (head && head->type == Node::TYPE_CLASS && static_cast<const ClassNode *>(head)->tool);
8834 }
8835
8836 const GDScriptParser::Node *GDScriptParser::get_parse_tree() const {
8837
8838 return head;
8839 }
8840
8841 void GDScriptParser::clear() {
8842
8843 while (list) {
8844
8845 Node *l = list;
8846 list = list->next;
8847 memdelete(l);
8848 }
8849
8850 head = NULL;
8851 list = NULL;
8852
8853 completion_type = COMPLETION_NONE;
8854 completion_node = NULL;
8855 completion_class = NULL;
8856 completion_function = NULL;
8857 completion_block = NULL;
8858 current_block = NULL;
8859 current_class = NULL;
8860
8861 completion_found = false;
8862 rpc_mode = MultiplayerAPI::RPC_MODE_DISABLED;
8863
8864 current_function = NULL;
8865
8866 validating = false;
8867 for_completion = false;
8868 error_set = false;
8869 indent_level.clear();
8870 indent_level.push_back(IndentLevel(0, 0));
8871 error_line = 0;
8872 error_column = 0;
8873 pending_newline = -1;
8874 parenthesis = 0;
8875 current_export.type = Variant::NIL;
8876 check_types = true;
8877 dependencies_only = false;
8878 dependencies.clear();
8879 error = "";
8880 #ifdef DEBUG_ENABLED
8881 safe_lines = NULL;
8882 #endif // DEBUG_ENABLED
8883 }
8884
8885 GDScriptParser::CompletionType GDScriptParser::get_completion_type() {
8886
8887 return completion_type;
8888 }
8889
8890 StringName GDScriptParser::get_completion_cursor() {
8891
8892 return completion_cursor;
8893 }
8894
8895 int GDScriptParser::get_completion_line() {
8896
8897 return completion_line;
8898 }
8899
8900 Variant::Type GDScriptParser::get_completion_built_in_constant() {
8901
8902 return completion_built_in_constant;
8903 }
8904
8905 GDScriptParser::Node *GDScriptParser::get_completion_node() {
8906
8907 return completion_node;
8908 }
8909
8910 GDScriptParser::BlockNode *GDScriptParser::get_completion_block() {
8911
8912 return completion_block;
8913 }
8914
8915 GDScriptParser::ClassNode *GDScriptParser::get_completion_class() {
8916
8917 return completion_class;
8918 }
8919
8920 GDScriptParser::FunctionNode *GDScriptParser::get_completion_function() {
8921
8922 return completion_function;
8923 }
8924
8925 int GDScriptParser::get_completion_argument_index() {
8926
8927 return completion_argument;
8928 }
8929
8930 int GDScriptParser::get_completion_identifier_is_function() {
8931
8932 return completion_ident_is_call;
8933 }
8934
8935 GDScriptParser::GDScriptParser() {
8936
8937 head = NULL;
8938 list = NULL;
8939 tokenizer = NULL;
8940 pending_newline = -1;
8941 clear();
8942 }
8943
8944 GDScriptParser::~GDScriptParser() {
8945
8946 clear();
8947 }
8948