diff options
Diffstat (limited to 'modules/gdscript')
15 files changed, 77 insertions, 19 deletions
diff --git a/modules/gdscript/gdscript_analyzer.cpp b/modules/gdscript/gdscript_analyzer.cpp index 23e88ae059..aa62ad20ff 100644 --- a/modules/gdscript/gdscript_analyzer.cpp +++ b/modules/gdscript/gdscript_analyzer.cpp @@ -175,6 +175,11 @@ Error GDScriptAnalyzer::check_native_member_name_conflict(const StringName &p_me return ERR_PARSE_ERROR; } + if (GDScriptParser::get_builtin_type(p_member_name) != Variant::VARIANT_MAX) { + push_error(vformat(R"(The member "%s" cannot have the same name as a builtin type.)", p_member_name), p_member_node); + return ERR_PARSE_ERROR; + } + return OK; } diff --git a/modules/gdscript/gdscript_compiler.cpp b/modules/gdscript/gdscript_compiler.cpp index a8aef84db3..947224e93e 100644 --- a/modules/gdscript/gdscript_compiler.cpp +++ b/modules/gdscript/gdscript_compiler.cpp @@ -1071,19 +1071,25 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_expression(CodeGen &code } } - GDScriptCodeGenerator::Address assigned = _parse_expression(codegen, r_error, assignment->assigned_value); - GDScriptCodeGenerator::Address op_result; + GDScriptCodeGenerator::Address assigned_value = _parse_expression(codegen, r_error, assignment->assigned_value); if (r_error) { return GDScriptCodeGenerator::Address(); } - if (assignment->operation != GDScriptParser::AssignmentNode::OP_NONE) { + GDScriptCodeGenerator::Address to_assign; + bool has_operation = assignment->operation != GDScriptParser::AssignmentNode::OP_NONE; + if (has_operation) { // Perform operation. - op_result = codegen.add_temporary(); - gen->write_binary_operator(op_result, assignment->variant_op, target, assigned); + GDScriptCodeGenerator::Address op_result = codegen.add_temporary(); + GDScriptCodeGenerator::Address og_value = _parse_expression(codegen, r_error, assignment->assignee); + gen->write_binary_operator(op_result, assignment->variant_op, og_value, assigned_value); + to_assign = op_result; + + if (og_value.mode == GDScriptCodeGenerator::Address::TEMPORARY) { + gen->pop_temporary(); + } } else { - op_result = assigned; - assigned = GDScriptCodeGenerator::Address(); + to_assign = assigned_value; } GDScriptDataType assign_type = _gdtype_from_datatype(assignment->assignee->get_datatype()); @@ -1091,25 +1097,25 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_expression(CodeGen &code if (has_setter && !is_in_setter) { // Call setter. Vector<GDScriptCodeGenerator::Address> args; - args.push_back(op_result); + args.push_back(to_assign); gen->write_call(GDScriptCodeGenerator::Address(), GDScriptCodeGenerator::Address(GDScriptCodeGenerator::Address::SELF), setter_function, args); } else { // Just assign. if (assignment->use_conversion_assign) { - gen->write_assign_with_conversion(target, op_result); + gen->write_assign_with_conversion(target, to_assign); } else { - gen->write_assign(target, op_result); + gen->write_assign(target, to_assign); } } - if (op_result.mode == GDScriptCodeGenerator::Address::TEMPORARY) { - gen->pop_temporary(); + if (to_assign.mode == GDScriptCodeGenerator::Address::TEMPORARY) { + gen->pop_temporary(); // Pop assigned value or temp operation result. } - if (assigned.mode == GDScriptCodeGenerator::Address::TEMPORARY) { - gen->pop_temporary(); + if (has_operation && assigned_value.mode == GDScriptCodeGenerator::Address::TEMPORARY) { + gen->pop_temporary(); // Pop assigned value if not done before. } if (target.mode == GDScriptCodeGenerator::Address::TEMPORARY) { - gen->pop_temporary(); + gen->pop_temporary(); // Pop the target to assignment. } } return GDScriptCodeGenerator::Address(); // Assignment does not return a value. diff --git a/modules/gdscript/gdscript_editor.cpp b/modules/gdscript/gdscript_editor.cpp index 2f8a054b2a..044ac4b661 100644 --- a/modules/gdscript/gdscript_editor.cpp +++ b/modules/gdscript/gdscript_editor.cpp @@ -637,7 +637,7 @@ static void _get_directory_contents(EditorFileSystemDirectory *p_dir, Map<String } static void _find_annotation_arguments(const GDScriptParser::AnnotationNode *p_annotation, int p_argument, const String p_quote_style, Map<String, ScriptCodeCompletionOption> &r_result) { - if (p_annotation->name == "@export_range" || p_annotation->name == "@export_exp_range") { + if (p_annotation->name == "@export_range") { if (p_argument == 3 || p_argument == 4) { // Slider hint. ScriptCodeCompletionOption slider1("or_greater", ScriptCodeCompletionOption::KIND_PLAIN_TEXT); diff --git a/modules/gdscript/language_server/gdscript_workspace.cpp b/modules/gdscript/language_server/gdscript_workspace.cpp index 86b3a3a326..f4b55cac02 100644 --- a/modules/gdscript/language_server/gdscript_workspace.cpp +++ b/modules/gdscript/language_server/gdscript_workspace.cpp @@ -603,7 +603,7 @@ void GDScriptWorkspace::completion(const lsp::CompletionParams &p_params, List<S } } -const lsp::DocumentSymbol *GDScriptWorkspace::resolve_symbol(const lsp::TextDocumentPositionParams &p_doc_pos, const String &p_symbol_name, bool p_func_requred) { +const lsp::DocumentSymbol *GDScriptWorkspace::resolve_symbol(const lsp::TextDocumentPositionParams &p_doc_pos, const String &p_symbol_name, bool p_func_required) { const lsp::DocumentSymbol *symbol = nullptr; String path = get_file_path(p_doc_pos.textDocument.uri); @@ -628,7 +628,10 @@ const lsp::DocumentSymbol *GDScriptWorkspace::resolve_symbol(const lsp::TextDocu } else { ScriptLanguage::LookupResult ret; - if (OK == GDScriptLanguage::get_singleton()->lookup_code(parser->get_text_for_lookup_symbol(pos, symbol_identifier, p_func_requred), symbol_identifier, path, nullptr, ret)) { + if (symbol_identifier == "new" && parser->get_lines()[p_doc_pos.position.line].replace(" ", "").replace("\t", "").find("new(") > -1) { + symbol_identifier = "_init"; + } + if (OK == GDScriptLanguage::get_singleton()->lookup_code(parser->get_text_for_lookup_symbol(pos, symbol_identifier, p_func_required), symbol_identifier, path, nullptr, ret)) { if (ret.type == ScriptLanguage::LookupResult::RESULT_SCRIPT_LOCATION) { String target_script_path = path; if (!ret.script.is_null()) { diff --git a/modules/gdscript/language_server/gdscript_workspace.h b/modules/gdscript/language_server/gdscript_workspace.h index e5cd4d9824..6f5600b5cf 100644 --- a/modules/gdscript/language_server/gdscript_workspace.h +++ b/modules/gdscript/language_server/gdscript_workspace.h @@ -87,7 +87,7 @@ public: void publish_diagnostics(const String &p_path); void completion(const lsp::CompletionParams &p_params, List<ScriptCodeCompletionOption> *r_options); - const lsp::DocumentSymbol *resolve_symbol(const lsp::TextDocumentPositionParams &p_doc_pos, const String &p_symbol_name = "", bool p_func_requred = false); + const lsp::DocumentSymbol *resolve_symbol(const lsp::TextDocumentPositionParams &p_doc_pos, const String &p_symbol_name = "", bool p_func_required = false); void resolve_related_symbols(const lsp::TextDocumentPositionParams &p_doc_pos, List<const lsp::DocumentSymbol *> &r_list); const lsp::DocumentSymbol *resolve_native_symbol(const lsp::NativeSymbolInspectParams &p_params); void resolve_document_links(const String &p_uri, List<lsp::DocumentLink> &r_list); diff --git a/modules/gdscript/tests/scripts/analyzer/errors/class_name_shadows_builtin_type.gd b/modules/gdscript/tests/scripts/analyzer/errors/class_name_shadows_builtin_type.gd new file mode 100644 index 0000000000..b84ccdce81 --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/errors/class_name_shadows_builtin_type.gd @@ -0,0 +1,5 @@ +class Vector2: + pass + +func test(): + pass diff --git a/modules/gdscript/tests/scripts/analyzer/errors/class_name_shadows_builtin_type.out b/modules/gdscript/tests/scripts/analyzer/errors/class_name_shadows_builtin_type.out new file mode 100644 index 0000000000..87863baf75 --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/errors/class_name_shadows_builtin_type.out @@ -0,0 +1,2 @@ +GDTEST_ANALYZER_ERROR +The member "Vector2" cannot have the same name as a builtin type. diff --git a/modules/gdscript/tests/scripts/analyzer/errors/constant_name_shadows_builtin_type.gd b/modules/gdscript/tests/scripts/analyzer/errors/constant_name_shadows_builtin_type.gd new file mode 100644 index 0000000000..a7c0a29a69 --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/errors/constant_name_shadows_builtin_type.gd @@ -0,0 +1,4 @@ +const Vector2 = 0 + +func test(): + pass diff --git a/modules/gdscript/tests/scripts/analyzer/errors/constant_name_shadows_builtin_type.out b/modules/gdscript/tests/scripts/analyzer/errors/constant_name_shadows_builtin_type.out new file mode 100644 index 0000000000..87863baf75 --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/errors/constant_name_shadows_builtin_type.out @@ -0,0 +1,2 @@ +GDTEST_ANALYZER_ERROR +The member "Vector2" cannot have the same name as a builtin type. diff --git a/modules/gdscript/tests/scripts/analyzer/errors/enum_name_shadows_builtin_type.gd b/modules/gdscript/tests/scripts/analyzer/errors/enum_name_shadows_builtin_type.gd new file mode 100644 index 0000000000..930f91b389 --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/errors/enum_name_shadows_builtin_type.gd @@ -0,0 +1,4 @@ +enum Vector2 { A, B } + +func test(): + pass diff --git a/modules/gdscript/tests/scripts/analyzer/errors/enum_name_shadows_builtin_type.out b/modules/gdscript/tests/scripts/analyzer/errors/enum_name_shadows_builtin_type.out new file mode 100644 index 0000000000..87863baf75 --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/errors/enum_name_shadows_builtin_type.out @@ -0,0 +1,2 @@ +GDTEST_ANALYZER_ERROR +The member "Vector2" cannot have the same name as a builtin type. diff --git a/modules/gdscript/tests/scripts/analyzer/errors/variable_name_shadows_builtin_type.gd b/modules/gdscript/tests/scripts/analyzer/errors/variable_name_shadows_builtin_type.gd new file mode 100644 index 0000000000..7cba29884c --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/errors/variable_name_shadows_builtin_type.gd @@ -0,0 +1,4 @@ +var Vector2 + +func test(): + pass diff --git a/modules/gdscript/tests/scripts/analyzer/errors/variable_name_shadows_builtin_type.out b/modules/gdscript/tests/scripts/analyzer/errors/variable_name_shadows_builtin_type.out new file mode 100644 index 0000000000..87863baf75 --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/errors/variable_name_shadows_builtin_type.out @@ -0,0 +1,2 @@ +GDTEST_ANALYZER_ERROR +The member "Vector2" cannot have the same name as a builtin type. diff --git a/modules/gdscript/tests/scripts/runtime/features/property_with_operator_assignment.gd b/modules/gdscript/tests/scripts/runtime/features/property_with_operator_assignment.gd new file mode 100644 index 0000000000..3eb02816ed --- /dev/null +++ b/modules/gdscript/tests/scripts/runtime/features/property_with_operator_assignment.gd @@ -0,0 +1,11 @@ +#GDTEST_OK +var prop : int = 0: + get: + return prop + set(value): + prop = value % 7 + +func test(): + for i in 7: + prop += 1 + print(prop) diff --git a/modules/gdscript/tests/scripts/runtime/features/property_with_operator_assignment.out b/modules/gdscript/tests/scripts/runtime/features/property_with_operator_assignment.out new file mode 100644 index 0000000000..76157853f2 --- /dev/null +++ b/modules/gdscript/tests/scripts/runtime/features/property_with_operator_assignment.out @@ -0,0 +1,8 @@ +GDTEST_OK +1 +2 +3 +4 +5 +6 +0 |