diff options
Diffstat (limited to 'modules/gdscript/gdscript_editor.cpp')
-rw-r--r-- | modules/gdscript/gdscript_editor.cpp | 117 |
1 files changed, 87 insertions, 30 deletions
diff --git a/modules/gdscript/gdscript_editor.cpp b/modules/gdscript/gdscript_editor.cpp index c00036c9f0..48a6e3fb51 100644 --- a/modules/gdscript/gdscript_editor.cpp +++ b/modules/gdscript/gdscript_editor.cpp @@ -61,8 +61,8 @@ bool GDScriptLanguage::is_using_templates() { } Ref<Script> GDScriptLanguage::make_template(const String &p_template, const String &p_class_name, const String &p_base_class_name) const { - Ref<GDScript> script; - script.instantiate(); + Ref<GDScript> scr; + scr.instantiate(); String processed_template = p_template; bool type_hints = false; #ifdef TOOLS_ENABLED @@ -82,8 +82,8 @@ Ref<Script> GDScriptLanguage::make_template(const String &p_template, const Stri processed_template = processed_template.replace("_BASE_", p_base_class_name) .replace("_CLASS_", p_class_name) .replace("_TS_", _get_indentation()); - script->set_source_code(processed_template); - return script; + scr->set_source_code(processed_template); + return scr; } Vector<ScriptLanguage::ScriptTemplate> GDScriptLanguage::get_built_in_templates(StringName p_object) { @@ -318,10 +318,10 @@ void GDScriptLanguage::debug_get_stack_level_members(int p_level, List<String> * return; } - Ref<GDScript> script = instance->get_script(); - ERR_FAIL_COND(script.is_null()); + Ref<GDScript> scr = instance->get_script(); + ERR_FAIL_COND(scr.is_null()); - const HashMap<StringName, GDScript::MemberInfo> &mi = script->debug_get_member_indices(); + const HashMap<StringName, GDScript::MemberInfo> &mi = scr->debug_get_member_indices(); for (const KeyValue<StringName, GDScript::MemberInfo> &E : mi) { p_members->push_back(E.key); @@ -344,7 +344,7 @@ ScriptInstance *GDScriptLanguage::debug_get_stack_level_instance(int p_level) { void GDScriptLanguage::debug_get_globals(List<String> *p_globals, List<Variant> *p_values, int p_max_subitems, int p_max_depth) { const HashMap<StringName, int> &name_idx = GDScriptLanguage::get_singleton()->get_global_map(); - const Variant *globals = GDScriptLanguage::get_singleton()->get_global_array(); + const Variant *gl_array = GDScriptLanguage::get_singleton()->get_global_array(); List<Pair<String, Variant>> cinfo; get_public_constants(&cinfo); @@ -365,7 +365,7 @@ void GDScriptLanguage::debug_get_globals(List<String> *p_globals, List<Variant> continue; } - const Variant &var = globals[E.value]; + const Variant &var = gl_array[E.value]; if (Object *obj = var) { if (Object::cast_to<GDScriptNativeClass>(obj)) { continue; @@ -766,7 +766,7 @@ static void _find_annotation_arguments(const GDScriptParser::AnnotationNode *p_a ScriptLanguage::CodeCompletionOption slider2("or_less", ScriptLanguage::CODE_COMPLETION_KIND_PLAIN_TEXT); slider2.insert_text = slider2.display.quote(p_quote_style); r_result.insert(slider2.display, slider2); - ScriptLanguage::CodeCompletionOption slider3("no_slider", ScriptLanguage::CODE_COMPLETION_KIND_PLAIN_TEXT); + ScriptLanguage::CodeCompletionOption slider3("hide_slider", ScriptLanguage::CODE_COMPLETION_KIND_PLAIN_TEXT); slider3.insert_text = slider3.display.quote(p_quote_style); r_result.insert(slider3.display, slider3); } @@ -1205,8 +1205,8 @@ static void _find_identifiers(const GDScriptParser::CompletionContext &p_context _find_built_in_variants(r_result); static const char *_keywords[] = { - "false", "PI", "TAU", "INF", "NAN", "self", "true", "breakpoint", "tool", "super", - "break", "continue", "pass", "return", + "true", "false", "PI", "TAU", "INF", "NAN", "null", "self", "super", + "break", "breakpoint", "continue", "pass", "return", nullptr }; @@ -1218,7 +1218,7 @@ static void _find_identifiers(const GDScriptParser::CompletionContext &p_context } static const char *_keywords_with_space[] = { - "and", "in", "not", "or", "as", "class", "extends", "is", "func", "signal", "await", + "and", "not", "or", "in", "as", "class", "class_name", "extends", "is", "func", "signal", "await", "const", "enum", "static", "var", "if", "elif", "else", "for", "match", "while", nullptr }; @@ -2511,9 +2511,60 @@ static void _find_call_arguments(GDScriptParser::CompletionContext &p_context, c } } +static bool _get_subscript_type(GDScriptParser::CompletionContext &p_context, const GDScriptParser::SubscriptNode *p_subscript, GDScriptParser::DataType &r_base_type, Variant *r_base = nullptr) { + if (p_subscript->base->type == GDScriptParser::Node::IDENTIFIER) { + const GDScriptParser::GetNodeNode *get_node = nullptr; + const GDScriptParser::IdentifierNode *identifier_node = static_cast<GDScriptParser::IdentifierNode *>(p_subscript->base); + + switch (identifier_node->source) { + case GDScriptParser::IdentifierNode::Source::MEMBER_VARIABLE: { + if (p_context.current_class != nullptr) { + const StringName &member_name = identifier_node->name; + const GDScriptParser::ClassNode *current_class = p_context.current_class; + + if (current_class->has_member(member_name)) { + const GDScriptParser::ClassNode::Member &member = current_class->get_member(member_name); + + if (member.type == GDScriptParser::ClassNode::Member::VARIABLE) { + const GDScriptParser::VariableNode *variable = static_cast<GDScriptParser::VariableNode *>(member.variable); + + if (variable->initializer && variable->initializer->type == GDScriptParser::Node::GET_NODE) { + get_node = static_cast<GDScriptParser::GetNodeNode *>(variable->initializer); + } + } + } + } + } break; + case GDScriptParser::IdentifierNode::Source::LOCAL_VARIABLE: { + if (identifier_node->next != nullptr && identifier_node->next->type == GDScriptParser::ClassNode::Node::GET_NODE) { + get_node = static_cast<GDScriptParser::GetNodeNode *>(identifier_node->next); + } + } break; + default: + break; + } + + if (get_node != nullptr) { + const Object *node = p_context.base->call("get_node_or_null", NodePath(get_node->full_path)); + if (node != nullptr) { + if (r_base != nullptr) { + *r_base = node; + } + r_base_type.type_source = GDScriptParser::DataType::ANNOTATED_EXPLICIT; + r_base_type.kind = GDScriptParser::DataType::NATIVE; + r_base_type.native_type = node->get_class_name(); + r_base_type.builtin_type = Variant::OBJECT; + return true; + } + } + } + + return false; +} + static void _find_call_arguments(GDScriptParser::CompletionContext &p_context, const GDScriptParser::Node *p_call, int p_argidx, HashMap<String, ScriptLanguage::CodeCompletionOption> &r_result, bool &r_forced, String &r_arghint) { if (p_call->type == GDScriptParser::Node::PRELOAD) { - if (p_argidx == 0 && bool(EditorSettings::get_singleton()->get("text_editor/completion/complete_file_paths"))) { + if (p_argidx == 0 && bool(EDITOR_GET("text_editor/completion/complete_file_paths"))) { _get_directory_contents(EditorFileSystem::get_singleton()->get_filesystem(), r_result); } @@ -2561,13 +2612,17 @@ static void _find_call_arguments(GDScriptParser::CompletionContext &p_context, c } } - if (subscript->is_attribute) { - GDScriptCompletionIdentifier ci; - if (_guess_expression_type(p_context, subscript->base, ci)) { - base_type = ci.type; - base = ci.value; - } else { - return; + if (p_context.base != nullptr && subscript->is_attribute) { + bool found_type = _get_subscript_type(p_context, subscript, base_type, &base); + + if (!found_type) { + GDScriptCompletionIdentifier ci; + if (_guess_expression_type(p_context, subscript->base, ci)) { + base_type = ci.type; + base = ci.value; + } else { + return; + } } _static = base_type.is_meta_type; @@ -2765,7 +2820,8 @@ static void _find_call_arguments(GDScriptParser::CompletionContext &p_context, c const GDScriptParser::SubscriptNode *attr = static_cast<const GDScriptParser::SubscriptNode *>(completion_context.node); if (attr->base) { GDScriptCompletionIdentifier base; - if (!_guess_expression_type(completion_context, attr->base, base)) { + bool found_type = _get_subscript_type(completion_context, attr, base.type); + if (!found_type && !_guess_expression_type(completion_context, attr->base, base)) { break; } @@ -2820,7 +2876,7 @@ static void _find_call_arguments(GDScriptParser::CompletionContext &p_context, c r_forced = true; } break; case GDScriptParser::COMPLETION_RESOURCE_PATH: { - if (EditorSettings::get_singleton()->get("text_editor/completion/complete_file_paths")) { + if (EDITOR_GET("text_editor/completion/complete_file_paths")) { _get_directory_contents(EditorFileSystem::get_singleton()->get_filesystem(), options); r_forced = true; } @@ -3051,8 +3107,9 @@ static Error _lookup_symbol_from_base(const GDScriptParser::DataType &p_base, co r_result.type = ScriptLanguage::LOOKUP_RESULT_SCRIPT_LOCATION; r_result.location = base_type.class_type->get_member(p_symbol).get_line(); r_result.class_path = base_type.script_path; - r_result.script = GDScriptCache::get_shallow_script(r_result.class_path); - return OK; + Error err = OK; + r_result.script = GDScriptCache::get_shallow_script(r_result.class_path, err); + return err; } base_type = base_type.class_type->base_type; } @@ -3302,17 +3359,17 @@ static Error _lookup_symbol_from_base(const GDScriptParser::DataType &p_base, co if (ProjectSettings::get_singleton()->has_autoload(p_symbol)) { const ProjectSettings::AutoloadInfo &autoload = ProjectSettings::get_singleton()->get_autoload(p_symbol); if (autoload.is_singleton) { - String script = autoload.path; - if (!script.ends_with(".gd")) { + String scr_path = autoload.path; + if (!scr_path.ends_with(".gd")) { // Not a script, try find the script anyway, // may have some success. - script = script.get_basename() + ".gd"; + scr_path = scr_path.get_basename() + ".gd"; } - if (FileAccess::exists(script)) { + if (FileAccess::exists(scr_path)) { r_result.type = ScriptLanguage::LOOKUP_RESULT_SCRIPT_LOCATION; r_result.location = 0; - r_result.script = ResourceLoader::load(script); + r_result.script = ResourceLoader::load(scr_path); return OK; } } |