summaryrefslogtreecommitdiffstats
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.cpp44
1 files changed, 37 insertions, 7 deletions
diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp
index f3a4f2eaa6..8293990dc6 100644
--- a/modules/gdscript/gdscript_parser.cpp
+++ b/modules/gdscript/gdscript_parser.cpp
@@ -629,7 +629,7 @@ GDScriptParser::ClassNode *GDScriptParser::find_class(const String &p_qualified_
// Starts at index 1 because index 0 was handled above.
for (int i = 1; result != nullptr && i < class_names.size(); i++) {
- String current_name = class_names[i];
+ const String &current_name = class_names[i];
GDScriptParser::ClassNode *next = nullptr;
if (result->has_member(current_name)) {
GDScriptParser::ClassNode::Member member = result->get_member(current_name);
@@ -1120,7 +1120,12 @@ void GDScriptParser::parse_property_getter(VariableNode *p_variable) {
case VariableNode::PROP_INLINE: {
FunctionNode *function = alloc_node<FunctionNode>();
- consume(GDScriptTokenizer::Token::COLON, R"(Expected ":" after "get".)");
+ if (match(GDScriptTokenizer::Token::PARENTHESIS_OPEN)) {
+ consume(GDScriptTokenizer::Token::PARENTHESIS_CLOSE, R"*(Expected ")" after "get(".)*");
+ consume(GDScriptTokenizer::Token::COLON, R"*(Expected ":" after "get()".)*");
+ } else {
+ consume(GDScriptTokenizer::Token::COLON, R"(Expected ":" or "(" after "get".)");
+ }
IdentifierNode *identifier = alloc_node<IdentifierNode>();
complete_extents(identifier);
@@ -1268,8 +1273,7 @@ GDScriptParser::EnumNode *GDScriptParser::parse_enum(bool p_is_static) {
EnumNode *enum_node = alloc_node<EnumNode>();
bool named = false;
- if (check(GDScriptTokenizer::Token::IDENTIFIER)) {
- advance();
+ if (match(GDScriptTokenizer::Token::IDENTIFIER)) {
enum_node->identifier = parse_identifier();
named = true;
}
@@ -3281,6 +3285,19 @@ GDScriptParser::ExpressionNode *GDScriptParser::parse_lambda(ExpressionNode *p_p
}
GDScriptParser::ExpressionNode *GDScriptParser::parse_type_test(ExpressionNode *p_previous_operand, bool p_can_assign) {
+ // x is not int
+ // ^ ^^^ ExpressionNode, TypeNode
+ // ^^^^^^^^^^^^ TypeTestNode
+ // ^^^^^^^^^^^^ UnaryOpNode
+ UnaryOpNode *not_node = nullptr;
+ if (match(GDScriptTokenizer::Token::NOT)) {
+ not_node = alloc_node<UnaryOpNode>();
+ not_node->operation = UnaryOpNode::OP_LOGIC_NOT;
+ not_node->variant_op = Variant::OP_NOT;
+ reset_extents(not_node, p_previous_operand);
+ update_extents(not_node);
+ }
+
TypeTestNode *type_test = alloc_node<TypeTestNode>();
reset_extents(type_test, p_previous_operand);
update_extents(type_test);
@@ -3289,8 +3306,21 @@ GDScriptParser::ExpressionNode *GDScriptParser::parse_type_test(ExpressionNode *
type_test->test_type = parse_type();
complete_extents(type_test);
+ if (not_node != nullptr) {
+ not_node->operand = type_test;
+ complete_extents(not_node);
+ }
+
if (type_test->test_type == nullptr) {
- push_error(R"(Expected type specifier after "is".)");
+ if (not_node == nullptr) {
+ push_error(R"(Expected type specifier after "is".)");
+ } else {
+ push_error(R"(Expected type specifier after "is not".)");
+ }
+ }
+
+ if (not_node != nullptr) {
+ return not_node;
}
return type_test;
@@ -3855,12 +3885,12 @@ bool GDScriptParser::validate_annotation_arguments(AnnotationNode *p_annotation)
bool GDScriptParser::tool_annotation(const AnnotationNode *p_annotation, Node *p_target, ClassNode *p_class) {
#ifdef DEBUG_ENABLED
- if (this->_is_tool) {
+ if (_is_tool) {
push_error(R"("@tool" annotation can only be used once.)", p_annotation);
return false;
}
#endif // DEBUG_ENABLED
- this->_is_tool = true;
+ _is_tool = true;
return true;
}