summaryrefslogtreecommitdiff
path: root/modules/gdscript/gdscript_parser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'modules/gdscript/gdscript_parser.cpp')
-rw-r--r--modules/gdscript/gdscript_parser.cpp183
1 files changed, 112 insertions, 71 deletions
diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp
index ef1a282e51..dcf5d35e36 100644
--- a/modules/gdscript/gdscript_parser.cpp
+++ b/modules/gdscript/gdscript_parser.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -2689,6 +2689,7 @@ void GDScriptParser::_transform_match_statment(MatchNode *p_match_statement) {
op->op = OperatorNode::OP_ASSIGN;
op->arguments.push_back(id2);
op->arguments.push_back(local_var->assign);
+ local_var->assign_op = op;
branch->body->statements.push_front(op);
branch->body->statements.push_front(local_var);
@@ -2866,7 +2867,6 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) {
assigned = _get_default_value_for_type(lv->datatype, var_line);
}
- lv->assign = assigned;
//must be added later, to avoid self-referencing.
p_block->variables.insert(n, lv);
@@ -4045,7 +4045,13 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
if (tokenizer->get_token() == GDScriptTokenizer::TK_PARENTHESIS_OPEN) {
- tokenizer->advance();
+#define _ADVANCE_AND_CONSUME_NEWLINES \
+ do { \
+ tokenizer->advance(); \
+ } while (tokenizer->get_token() == GDScriptTokenizer::TK_NEWLINE)
+
+ _ADVANCE_AND_CONSUME_NEWLINES;
+ parenthesis++;
String hint_prefix = "";
bool is_arrayed = false;
@@ -4075,11 +4081,11 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
}
current_export.type = type;
current_export.usage |= PROPERTY_USAGE_SCRIPT_VARIABLE;
- tokenizer->advance();
+ _ADVANCE_AND_CONSUME_NEWLINES;
if (tokenizer->get_token() == GDScriptTokenizer::TK_COMMA) {
// hint expected next!
- tokenizer->advance();
+ _ADVANCE_AND_CONSUME_NEWLINES;
switch (type) {
@@ -4087,7 +4093,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
if (tokenizer->get_token() == GDScriptTokenizer::TK_IDENTIFIER && tokenizer->get_token_identifier() == "FLAGS") {
- tokenizer->advance();
+ _ADVANCE_AND_CONSUME_NEWLINES;
if (tokenizer->get_token() == GDScriptTokenizer::TK_PARENTHESIS_CLOSE) {
WARN_DEPRECATED_MSG("Exporting bit flags hint requires string constants.");
@@ -4099,7 +4105,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
}
current_export.hint = PROPERTY_HINT_FLAGS;
- tokenizer->advance();
+ _ADVANCE_AND_CONSUME_NEWLINES;
bool first = true;
while (true) {
@@ -4118,7 +4124,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
current_export.hint_string += c.xml_escape();
- tokenizer->advance();
+ _ADVANCE_AND_CONSUME_NEWLINES;
if (tokenizer->get_token() == GDScriptTokenizer::TK_PARENTHESIS_CLOSE)
break;
@@ -4127,7 +4133,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
_set_error("Expected \")\" or \",\" in the named bit flags hint.");
return;
}
- tokenizer->advance();
+ _ADVANCE_AND_CONSUME_NEWLINES;
}
break;
@@ -4135,7 +4141,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
if (tokenizer->get_token() == GDScriptTokenizer::TK_IDENTIFIER && tokenizer->get_token_identifier() == "LAYERS_2D_RENDER") {
- tokenizer->advance();
+ _ADVANCE_AND_CONSUME_NEWLINES;
if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_CLOSE) {
_set_error("Expected \")\" in the layers 2D render hint.");
return;
@@ -4146,7 +4152,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
if (tokenizer->get_token() == GDScriptTokenizer::TK_IDENTIFIER && tokenizer->get_token_identifier() == "LAYERS_2D_PHYSICS") {
- tokenizer->advance();
+ _ADVANCE_AND_CONSUME_NEWLINES;
if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_CLOSE) {
_set_error("Expected \")\" in the layers 2D physics hint.");
return;
@@ -4157,7 +4163,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
if (tokenizer->get_token() == GDScriptTokenizer::TK_IDENTIFIER && tokenizer->get_token_identifier() == "LAYERS_3D_RENDER") {
- tokenizer->advance();
+ _ADVANCE_AND_CONSUME_NEWLINES;
if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_CLOSE) {
_set_error("Expected \")\" in the layers 3D render hint.");
return;
@@ -4168,7 +4174,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
if (tokenizer->get_token() == GDScriptTokenizer::TK_IDENTIFIER && tokenizer->get_token_identifier() == "LAYERS_3D_PHYSICS") {
- tokenizer->advance();
+ _ADVANCE_AND_CONSUME_NEWLINES;
if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_CLOSE) {
_set_error("Expected \")\" in the layers 3D physics hint.");
return;
@@ -4198,7 +4204,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
current_export.hint_string += c.xml_escape();
- tokenizer->advance();
+ _ADVANCE_AND_CONSUME_NEWLINES;
if (tokenizer->get_token() == GDScriptTokenizer::TK_PARENTHESIS_CLOSE)
break;
@@ -4208,7 +4214,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
return;
}
- tokenizer->advance();
+ _ADVANCE_AND_CONSUME_NEWLINES;
}
break;
@@ -4220,7 +4226,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
if (tokenizer->get_token() == GDScriptTokenizer::TK_IDENTIFIER && tokenizer->get_token_identifier() == "EASE") {
current_export.hint = PROPERTY_HINT_EXP_EASING;
- tokenizer->advance();
+ _ADVANCE_AND_CONSUME_NEWLINES;
if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_CLOSE) {
_set_error("Expected \")\" in the hint.");
return;
@@ -4232,7 +4238,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
if (tokenizer->get_token() == GDScriptTokenizer::TK_IDENTIFIER && tokenizer->get_token_identifier() == "EXP") {
current_export.hint = PROPERTY_HINT_EXP_RANGE;
- tokenizer->advance();
+ _ADVANCE_AND_CONSUME_NEWLINES;
if (tokenizer->get_token() == GDScriptTokenizer::TK_PARENTHESIS_CLOSE)
break;
@@ -4240,7 +4246,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
_set_error("Expected \")\" or \",\" in the exponential range hint.");
return;
}
- tokenizer->advance();
+ _ADVANCE_AND_CONSUME_NEWLINES;
} else
current_export.hint = PROPERTY_HINT_RANGE;
@@ -4248,7 +4254,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
if (tokenizer->get_token() == GDScriptTokenizer::TK_OP_SUB) {
sign = -1;
- tokenizer->advance();
+ _ADVANCE_AND_CONSUME_NEWLINES;
}
if (tokenizer->get_token() != GDScriptTokenizer::TK_CONSTANT || !tokenizer->get_token_constant().is_num()) {
@@ -4258,7 +4264,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
}
current_export.hint_string = rtos(sign * double(tokenizer->get_token_constant()));
- tokenizer->advance();
+ _ADVANCE_AND_CONSUME_NEWLINES;
if (tokenizer->get_token() == GDScriptTokenizer::TK_PARENTHESIS_CLOSE) {
current_export.hint_string = "0," + current_export.hint_string;
@@ -4272,12 +4278,12 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
return;
}
- tokenizer->advance();
+ _ADVANCE_AND_CONSUME_NEWLINES;
sign = 1.0;
if (tokenizer->get_token() == GDScriptTokenizer::TK_OP_SUB) {
sign = -1;
- tokenizer->advance();
+ _ADVANCE_AND_CONSUME_NEWLINES;
}
if (tokenizer->get_token() != GDScriptTokenizer::TK_CONSTANT || !tokenizer->get_token_constant().is_num()) {
@@ -4288,7 +4294,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
}
current_export.hint_string += "," + rtos(sign * double(tokenizer->get_token_constant()));
- tokenizer->advance();
+ _ADVANCE_AND_CONSUME_NEWLINES;
if (tokenizer->get_token() == GDScriptTokenizer::TK_PARENTHESIS_CLOSE)
break;
@@ -4300,11 +4306,11 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
return;
}
- tokenizer->advance();
+ _ADVANCE_AND_CONSUME_NEWLINES;
sign = 1.0;
if (tokenizer->get_token() == GDScriptTokenizer::TK_OP_SUB) {
sign = -1;
- tokenizer->advance();
+ _ADVANCE_AND_CONSUME_NEWLINES;
}
if (tokenizer->get_token() != GDScriptTokenizer::TK_CONSTANT || !tokenizer->get_token_constant().is_num()) {
@@ -4315,7 +4321,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
}
current_export.hint_string += "," + rtos(sign * double(tokenizer->get_token_constant()));
- tokenizer->advance();
+ _ADVANCE_AND_CONSUME_NEWLINES;
} break;
case Variant::STRING: {
@@ -4340,7 +4346,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
first = false;
current_export.hint_string += c.xml_escape();
- tokenizer->advance();
+ _ADVANCE_AND_CONSUME_NEWLINES;
if (tokenizer->get_token() == GDScriptTokenizer::TK_PARENTHESIS_CLOSE)
break;
@@ -4349,7 +4355,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
_set_error("Expected \")\" or \",\" in the enumeration hint.");
return;
}
- tokenizer->advance();
+ _ADVANCE_AND_CONSUME_NEWLINES;
}
break;
@@ -4357,13 +4363,13 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
if (tokenizer->get_token() == GDScriptTokenizer::TK_IDENTIFIER && tokenizer->get_token_identifier() == "DIR") {
- tokenizer->advance();
+ _ADVANCE_AND_CONSUME_NEWLINES;
if (tokenizer->get_token() == GDScriptTokenizer::TK_PARENTHESIS_CLOSE)
current_export.hint = PROPERTY_HINT_DIR;
else if (tokenizer->get_token() == GDScriptTokenizer::TK_COMMA) {
- tokenizer->advance();
+ _ADVANCE_AND_CONSUME_NEWLINES;
if (tokenizer->get_token() != GDScriptTokenizer::TK_IDENTIFIER || !(tokenizer->get_token_identifier() == "GLOBAL")) {
_set_error("Expected \"GLOBAL\" after comma in the directory hint.");
@@ -4374,7 +4380,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
return;
}
current_export.hint = PROPERTY_HINT_GLOBAL_DIR;
- tokenizer->advance();
+ _ADVANCE_AND_CONSUME_NEWLINES;
if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_CLOSE) {
_set_error("Expected \")\" in the hint.");
@@ -4390,11 +4396,11 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
if (tokenizer->get_token() == GDScriptTokenizer::TK_IDENTIFIER && tokenizer->get_token_identifier() == "FILE") {
current_export.hint = PROPERTY_HINT_FILE;
- tokenizer->advance();
+ _ADVANCE_AND_CONSUME_NEWLINES;
if (tokenizer->get_token() == GDScriptTokenizer::TK_COMMA) {
- tokenizer->advance();
+ _ADVANCE_AND_CONSUME_NEWLINES;
if (tokenizer->get_token() == GDScriptTokenizer::TK_IDENTIFIER && tokenizer->get_token_identifier() == "GLOBAL") {
@@ -4403,12 +4409,12 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
return;
}
current_export.hint = PROPERTY_HINT_GLOBAL_FILE;
- tokenizer->advance();
+ _ADVANCE_AND_CONSUME_NEWLINES;
if (tokenizer->get_token() == GDScriptTokenizer::TK_PARENTHESIS_CLOSE)
break;
else if (tokenizer->get_token() == GDScriptTokenizer::TK_COMMA)
- tokenizer->advance();
+ _ADVANCE_AND_CONSUME_NEWLINES;
else {
_set_error("Expected \")\" or \",\" in the hint.");
return;
@@ -4424,7 +4430,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
return;
}
current_export.hint_string = tokenizer->get_token_constant();
- tokenizer->advance();
+ _ADVANCE_AND_CONSUME_NEWLINES;
}
if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_CLOSE) {
@@ -4437,7 +4443,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
if (tokenizer->get_token() == GDScriptTokenizer::TK_IDENTIFIER && tokenizer->get_token_identifier() == "MULTILINE") {
current_export.hint = PROPERTY_HINT_MULTILINE_TEXT;
- tokenizer->advance();
+ _ADVANCE_AND_CONSUME_NEWLINES;
if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_CLOSE) {
_set_error("Expected \")\" in the hint.");
return;
@@ -4464,7 +4470,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
_set_error("Color type hint expects RGB or RGBA as hints.");
return;
}
- tokenizer->advance();
+ _ADVANCE_AND_CONSUME_NEWLINES;
} break;
default: {
@@ -4515,11 +4521,11 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
bool is_flags = false;
if (tokenizer->get_token() == GDScriptTokenizer::TK_COMMA) {
- tokenizer->advance();
+ _ADVANCE_AND_CONSUME_NEWLINES;
if (tokenizer->get_token() == GDScriptTokenizer::TK_IDENTIFIER && tokenizer->get_token_identifier() == "FLAGS") {
is_flags = true;
- tokenizer->advance();
+ _ADVANCE_AND_CONSUME_NEWLINES;
} else {
current_export = PropertyInfo();
_set_error("Expected \"FLAGS\" after comma.");
@@ -4563,6 +4569,9 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
return;
}
+ tokenizer->advance();
+ parenthesis--;
+
if (is_arrayed) {
hint_prefix += itos(current_export.type);
if (current_export.hint) {
@@ -4572,8 +4581,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
current_export.hint = PROPERTY_HINT_TYPE_STRING;
current_export.type = Variant::ARRAY;
}
-
- tokenizer->advance();
+#undef _ADVANCE_AND_CONSUME_NEWLINES
}
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) {
@@ -6957,6 +6965,17 @@ GDScriptParser::DataType GDScriptParser::_reduce_function_call_type(const Operat
if (error_set) return DataType();
+ // Special case: check copy constructor. Those are defined implicitly in Variant.
+ if (par_types.size() == 1) {
+ if (!par_types[0].has_type || (par_types[0].kind == DataType::BUILTIN && par_types[0].builtin_type == tn->vtype)) {
+ DataType result;
+ result.has_type = true;
+ result.kind = DataType::BUILTIN;
+ result.builtin_type = tn->vtype;
+ return result;
+ }
+ }
+
bool match = false;
List<MethodInfo> constructors;
Variant::get_constructor_list(tn->vtype, &constructors);
@@ -7629,6 +7648,11 @@ GDScriptParser::DataType GDScriptParser::_reduce_identifier_type(const DataType
void GDScriptParser::_check_class_level_types(ClassNode *p_class) {
+ // Names of internal object properties that we check to avoid overriding them.
+ // "__meta__" could also be in here, but since it doesn't really affect object metadata,
+ // it is okay to override it on script.
+ StringName script_name = CoreStringNames::get_singleton()->_script;
+
_mark_line_as_safe(p_class->line);
// Constants
@@ -7649,8 +7673,9 @@ void GDScriptParser::_check_class_level_types(ClassNode *p_class) {
c.expression->set_datatype(expr);
DataType tmp;
- if (_get_member_type(p_class->base_type, E->key(), tmp)) {
- _set_error("The member \"" + String(E->key()) + "\" already exists in a parent class.", c.expression->line);
+ const StringName &constant_name = E->key();
+ if (constant_name == script_name || _get_member_type(p_class->base_type, constant_name, tmp)) {
+ _set_error("The member \"" + String(constant_name) + "\" already exists in a parent class.", c.expression->line);
return;
}
}
@@ -7671,7 +7696,7 @@ void GDScriptParser::_check_class_level_types(ClassNode *p_class) {
ClassNode::Member &v = p_class->variables.write[i];
DataType tmp;
- if (_get_member_type(p_class->base_type, v.identifier, tmp)) {
+ if (v.identifier == script_name || _get_member_type(p_class->base_type, v.identifier, tmp)) {
_set_error("The member \"" + String(v.identifier) + "\" already exists in a parent class.", v.line);
return;
}
@@ -7848,12 +7873,12 @@ void GDScriptParser::_check_function_types(FunctionNode *p_function) {
def_type.is_constant = false;
p_function->argument_types.write[i] = def_type;
} else {
- p_function->return_type = _resolve_type(p_function->return_type, p_function->line);
+ p_function->argument_types.write[i] = _resolve_type(p_function->argument_types[i], p_function->line);
if (!_is_type_compatible(p_function->argument_types[i], def_type, true)) {
String arg_name = p_function->arguments[i];
_set_error("Value type (" + def_type.to_string() + ") doesn't match the type of argument '" +
- arg_name + "' (" + p_function->arguments[i] + ").",
+ arg_name + "' (" + p_function->argument_types[i].to_string() + ").",
p_function->line);
}
}
@@ -8039,6 +8064,7 @@ void GDScriptParser::_check_block_types(BlockNode *p_block) {
last_var_assign = lv->assign;
if (lv->assign) {
+ lv->assign_op->arguments[0]->set_datatype(lv->datatype);
DataType assign_type = _reduce_node_type(lv->assign);
#ifdef DEBUG_ENABLED
if (assign_type.has_type && assign_type.kind == DataType::BUILTIN && assign_type.builtin_type == Variant::NIL) {
@@ -8183,9 +8209,14 @@ void GDScriptParser::_check_block_types(BlockNode *p_block) {
if (lh_type.has_type && rh_type.may_yield && op->arguments[1]->type == Node::TYPE_OPERATOR) {
_add_warning(GDScriptWarning::FUNCTION_MAY_YIELD, op->line, _find_function_name(static_cast<OperatorNode *>(op->arguments[1])));
}
-#endif // DEBUG_ENABLED
+ bool type_match = check_types;
+#endif // DEBUG_ENABLED
if (check_types && !_is_type_compatible(lh_type, rh_type)) {
+#ifdef DEBUG_ENABLED
+ type_match = false;
+#endif // DEBUG_ENABLED
+
// Try supertype test
if (_is_type_compatible(rh_type, lh_type)) {
_mark_line_as_unsafe(op->line);
@@ -8197,23 +8228,29 @@ void GDScriptParser::_check_block_types(BlockNode *p_block) {
op->line);
return;
}
- // Replace assignment with implicit conversion
- BuiltInFunctionNode *convert = alloc_node<BuiltInFunctionNode>();
- convert->line = op->line;
- convert->function = GDScriptFunctions::TYPE_CONVERT;
-
- ConstantNode *tgt_type = alloc_node<ConstantNode>();
- tgt_type->line = op->line;
- tgt_type->value = (int)lh_type.builtin_type;
-
- OperatorNode *convert_call = alloc_node<OperatorNode>();
- convert_call->line = op->line;
- convert_call->op = OperatorNode::OP_CALL;
- convert_call->arguments.push_back(convert);
- convert_call->arguments.push_back(op->arguments[1]);
- convert_call->arguments.push_back(tgt_type);
-
- op->arguments.write[1] = convert_call;
+ if (op->op == OperatorNode::OP_ASSIGN) {
+ // Replace assignment with implicit conversion
+ BuiltInFunctionNode *convert = alloc_node<BuiltInFunctionNode>();
+ convert->line = op->line;
+ convert->function = GDScriptFunctions::TYPE_CONVERT;
+
+ ConstantNode *tgt_type = alloc_node<ConstantNode>();
+ tgt_type->line = op->line;
+ tgt_type->value = (int)lh_type.builtin_type;
+
+ OperatorNode *convert_call = alloc_node<OperatorNode>();
+ convert_call->line = op->line;
+ convert_call->op = OperatorNode::OP_CALL;
+ convert_call->arguments.push_back(convert);
+ convert_call->arguments.push_back(op->arguments[1]);
+ convert_call->arguments.push_back(tgt_type);
+
+ op->arguments.write[1] = convert_call;
+
+#ifdef DEBUG_ENABLED
+ type_match = true; // Since we are converting, the type is matching
+#endif // DEBUG_ENABLED
+ }
#ifdef DEBUG_ENABLED
if (lh_type.builtin_type == Variant::INT && rh_type.builtin_type == Variant::REAL) {
_add_warning(GDScriptWarning::NARROWING_CONVERSION, op->line);
@@ -8225,6 +8262,9 @@ void GDScriptParser::_check_block_types(BlockNode *p_block) {
if (!rh_type.has_type && (op->op != OperatorNode::OP_ASSIGN || lh_type.has_type || op->arguments[0]->type == Node::TYPE_OPERATOR)) {
_mark_line_as_unsafe(op->line);
}
+ op->datatype.has_type = type_match;
+#else
+ op->datatype.has_type = false;
#endif // DEBUG_ENABLED
} break;
case OperatorNode::OP_CALL:
@@ -8251,7 +8291,11 @@ void GDScriptParser::_check_block_types(BlockNode *p_block) {
_mark_line_as_safe(op->line);
_reduce_node_type(op); // Test for safety anyway
#ifdef DEBUG_ENABLED
- _add_warning(GDScriptWarning::STANDALONE_EXPRESSION, statement->line);
+ if (op->op == OperatorNode::OP_TERNARY_IF) {
+ _add_warning(GDScriptWarning::STANDALONE_TERNARY, statement->line);
+ } else {
+ _add_warning(GDScriptWarning::STANDALONE_EXPRESSION, statement->line);
+ }
#endif // DEBUG_ENABLED
}
}
@@ -8468,11 +8512,8 @@ Error GDScriptParser::_parse(const String &p_base_path) {
current_class = main_class;
current_function = NULL;
current_block = NULL;
-#ifdef DEBUG_ENABLED
+
if (for_completion) check_types = false;
-#else
- check_types = false;
-#endif
// Resolve all class-level stuff before getting into function blocks
_check_class_level_types(main_class);