diff options
Diffstat (limited to 'modules/gdscript')
-rw-r--r-- | modules/gdscript/gdscript_compiler.cpp | 69 | ||||
-rw-r--r-- | modules/gdscript/gdscript_editor.cpp | 3 | ||||
-rw-r--r-- | modules/gdscript/gdscript_parser.cpp | 22 | ||||
-rw-r--r-- | modules/gdscript/gdscript_parser.h | 1 | ||||
-rw-r--r-- | modules/gdscript/language_server/lsp.hpp | 2 |
5 files changed, 68 insertions, 29 deletions
diff --git a/modules/gdscript/gdscript_compiler.cpp b/modules/gdscript/gdscript_compiler.cpp index b491440d4c..06d628d23f 100644 --- a/modules/gdscript/gdscript_compiler.cpp +++ b/modules/gdscript/gdscript_compiler.cpp @@ -255,36 +255,59 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_expression(CodeGen &code } // Try class constants. - GDScript *owner = codegen.script; - while (owner) { - GDScript *scr = owner; - GDScriptNativeClass *nc = nullptr; - while (scr) { - if (scr->constants.has(identifier)) { - return GDScriptCodeGenerator::Address(GDScriptCodeGenerator::Address::CLASS_CONSTANT, gen->add_or_get_name(identifier)); // TODO: Get type here. + { + GDScript *owner = codegen.script; + while (owner) { + GDScript *scr = owner; + GDScriptNativeClass *nc = nullptr; + while (scr) { + if (scr->constants.has(identifier)) { + return GDScriptCodeGenerator::Address(GDScriptCodeGenerator::Address::CLASS_CONSTANT, gen->add_or_get_name(identifier)); // TODO: Get type here. + } + if (scr->native.is_valid()) { + nc = scr->native.ptr(); + } + scr = scr->_base; } - if (scr->native.is_valid()) { - nc = scr->native.ptr(); + + // Class C++ integer constant. + if (nc) { + bool success = false; + int constant = ClassDB::get_integer_constant(nc->get_name(), identifier, &success); + if (success) { + return codegen.add_constant(constant); + } } - scr = scr->_base; + + owner = owner->_owner; } + } - // Class C++ integer constant. - if (nc) { - bool success = false; - int constant = ClassDB::get_integer_constant(nc->get_name(), identifier, &success); - if (success) { - return codegen.add_constant(constant); + // Try signals and methods (can be made callables). + { + if (codegen.class_node->members_indices.has(identifier)) { + const GDScriptParser::ClassNode::Member &member = codegen.class_node->members[codegen.class_node->members_indices[identifier]]; + if (member.type == GDScriptParser::ClassNode::Member::FUNCTION || member.type == GDScriptParser::ClassNode::Member::SIGNAL) { + // Get like it was a property. + GDScriptCodeGenerator::Address temp = codegen.add_temporary(); // TODO: Get type here. + GDScriptCodeGenerator::Address self(GDScriptCodeGenerator::Address::SELF); + + gen->write_get_named(temp, identifier, self); + return temp; } } - owner = owner->_owner; - } + // Try in native base. + GDScript *scr = codegen.script; + GDScriptNativeClass *nc = nullptr; + while (scr) { + if (scr->native.is_valid()) { + nc = scr->native.ptr(); + } + scr = scr->_base; + } - // Try signals and methods (can be made callables); - if (codegen.class_node->members_indices.has(identifier)) { - const GDScriptParser::ClassNode::Member &member = codegen.class_node->members[codegen.class_node->members_indices[identifier]]; - if (member.type == GDScriptParser::ClassNode::Member::FUNCTION || member.type == GDScriptParser::ClassNode::Member::SIGNAL) { + if (nc && (ClassDB::has_signal(nc->get_name(), identifier) || ClassDB::has_method(nc->get_name(), identifier))) { // Get like it was a property. GDScriptCodeGenerator::Address temp = codegen.add_temporary(); // TODO: Get type here. GDScriptCodeGenerator::Address self(GDScriptCodeGenerator::Address::SELF); @@ -1153,7 +1176,7 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_match_pattern(CodeGen &c codegen.generator->write_and_left_operand(result_addr); // Check value equality. - codegen.generator->write_binary_operator(result_addr, Variant::OP_EQUAL, p_value_addr, expr_addr); + codegen.generator->write_binary_operator(equality_test_addr, Variant::OP_EQUAL, p_value_addr, expr_addr); codegen.generator->write_and_right_operand(equality_test_addr); // AND both type and value equality. diff --git a/modules/gdscript/gdscript_editor.cpp b/modules/gdscript/gdscript_editor.cpp index b17971cf93..a9975c8602 100644 --- a/modules/gdscript/gdscript_editor.cpp +++ b/modules/gdscript/gdscript_editor.cpp @@ -2261,10 +2261,9 @@ static void _find_call_arguments(GDScriptParser::CompletionContext &p_context, c } r_arghint = _make_arguments_hint(info, p_argidx); - return; } - if (ClassDB::is_parent_class(class_name, "Node") && (p_method == "get_node" || p_method == "has_node") && p_argidx == 0) { + if (p_argidx == 0 && ClassDB::is_parent_class(class_name, "Node") && (p_method == "get_node" || p_method == "has_node")) { // Get autoloads List<PropertyInfo> props; ProjectSettings::get_singleton()->get_property_list(&props); diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp index a77fb14064..08645d371c 100644 --- a/modules/gdscript/gdscript_parser.cpp +++ b/modules/gdscript/gdscript_parser.cpp @@ -2080,6 +2080,17 @@ GDScriptParser::ExpressionNode *GDScriptParser::parse_unary_operator(ExpressionN return operation; } +GDScriptParser::ExpressionNode *GDScriptParser::parse_binary_not_in_operator(ExpressionNode *p_previous_operand, bool p_can_assign) { + // check that NOT is followed by IN by consuming it before calling parse_binary_operator which will only receive a plain IN + consume(GDScriptTokenizer::Token::IN, R"(Expected "in" after "not" in content-test operator.)"); + ExpressionNode *in_operation = parse_binary_operator(p_previous_operand, p_can_assign); + UnaryOpNode *operation = alloc_node<UnaryOpNode>(); + operation->operation = UnaryOpNode::OP_LOGIC_NOT; + operation->variant_op = Variant::OP_NOT; + operation->operand = in_operation; + return operation; +} + GDScriptParser::ExpressionNode *GDScriptParser::parse_binary_operator(ExpressionNode *p_previous_operand, bool p_can_assign) { GDScriptTokenizer::Token op = previous; BinaryOpNode *operation = alloc_node<BinaryOpNode>(); @@ -2906,7 +2917,7 @@ GDScriptParser::ParseRule *GDScriptParser::get_rule(GDScriptTokenizer::Token::Ty // Logical { nullptr, &GDScriptParser::parse_binary_operator, PREC_LOGIC_AND }, // AND, { nullptr, &GDScriptParser::parse_binary_operator, PREC_LOGIC_OR }, // OR, - { &GDScriptParser::parse_unary_operator, nullptr, PREC_NONE }, // NOT, + { &GDScriptParser::parse_unary_operator, &GDScriptParser::parse_binary_not_in_operator, PREC_CONTENT_TEST }, // NOT, { nullptr, &GDScriptParser::parse_binary_operator, PREC_LOGIC_AND }, // AMPERSAND_AMPERSAND, { nullptr, &GDScriptParser::parse_binary_operator, PREC_LOGIC_OR }, // PIPE_PIPE, { &GDScriptParser::parse_unary_operator, nullptr, PREC_NONE }, // BANG, @@ -3157,11 +3168,16 @@ bool GDScriptParser::export_annotations(const AnnotationNode *p_annotation, Node push_error(R"(Cannot use "@export" annotation with variable without type or initializer, since type can't be inferred.)", p_annotation); return false; } - if (variable->initializer->type != Node::LITERAL) { + if (variable->initializer->type == Node::LITERAL) { + variable->export_info.type = static_cast<LiteralNode *>(variable->initializer)->value.get_type(); + } else if (variable->initializer->type == Node::ARRAY) { + variable->export_info.type = Variant::ARRAY; + } else if (variable->initializer->type == Node::DICTIONARY) { + variable->export_info.type = Variant::DICTIONARY; + } else { push_error(R"(To use "@export" annotation with type-less variable, the default value must be a literal.)", p_annotation); return false; } - variable->export_info.type = static_cast<LiteralNode *>(variable->initializer)->value.get_type(); } // else: Actual type will be set by the analyzer, which can infer the proper type. } diff --git a/modules/gdscript/gdscript_parser.h b/modules/gdscript/gdscript_parser.h index d59b68b602..a4b1d4c866 100644 --- a/modules/gdscript/gdscript_parser.h +++ b/modules/gdscript/gdscript_parser.h @@ -1285,6 +1285,7 @@ private: ExpressionNode *parse_builtin_constant(ExpressionNode *p_previous_operand, bool p_can_assign); ExpressionNode *parse_unary_operator(ExpressionNode *p_previous_operand, bool p_can_assign); ExpressionNode *parse_binary_operator(ExpressionNode *p_previous_operand, bool p_can_assign); + ExpressionNode *parse_binary_not_in_operator(ExpressionNode *p_previous_operand, bool p_can_assign); ExpressionNode *parse_ternary_operator(ExpressionNode *p_previous_operand, bool p_can_assign); ExpressionNode *parse_assignment(ExpressionNode *p_previous_operand, bool p_can_assign); ExpressionNode *parse_array(ExpressionNode *p_previous_operand, bool p_can_assign); diff --git a/modules/gdscript/language_server/lsp.hpp b/modules/gdscript/language_server/lsp.hpp index 96744a15d7..6635098be2 100644 --- a/modules/gdscript/language_server/lsp.hpp +++ b/modules/gdscript/language_server/lsp.hpp @@ -1661,7 +1661,7 @@ struct ServerCapabilities { signatureHelpProvider.triggerCharacters.push_back(","); signatureHelpProvider.triggerCharacters.push_back("("); dict["signatureHelpProvider"] = signatureHelpProvider.to_json(); - dict["codeLensProvider"] = false; // codeLensProvider.to_json(); + //dict["codeLensProvider"] = codeLensProvider.to_json(); dict["documentOnTypeFormattingProvider"] = documentOnTypeFormattingProvider.to_json(); dict["renameProvider"] = renameProvider.to_json(); dict["documentLinkProvider"] = documentLinkProvider.to_json(); |