diff options
Diffstat (limited to 'modules/gdscript')
-rw-r--r-- | modules/gdscript/gdscript.h | 2 | ||||
-rw-r--r-- | modules/gdscript/gdscript_editor.cpp | 219 | ||||
-rw-r--r-- | modules/gdscript/gdscript_parser.cpp | 55 | ||||
-rw-r--r-- | modules/gdscript/gdscript_parser.h | 4 |
4 files changed, 173 insertions, 107 deletions
diff --git a/modules/gdscript/gdscript.h b/modules/gdscript/gdscript.h index 1756f6eabc..a5ad23c75d 100644 --- a/modules/gdscript/gdscript.h +++ b/modules/gdscript/gdscript.h @@ -458,7 +458,7 @@ public: virtual bool can_inherit_from_file() { return true; } virtual int find_function(const String &p_function, const String &p_code) const; virtual String make_function(const String &p_class, const String &p_name, const PoolStringArray &p_args) const; - virtual Error complete_code(const String &p_code, const String &p_path, Object *p_owner, List<String> *r_options, bool &r_forced, String &r_call_hint); + virtual Error complete_code(const String &p_code, const String &p_path, Object *p_owner, List<ScriptCodeCompletionOption> *r_options, bool &r_forced, String &r_call_hint); #ifdef TOOLS_ENABLED virtual Error lookup_code(const String &p_code, const String &p_symbol, const String &p_path, Object *p_owner, LookupResult &r_result); #endif diff --git a/modules/gdscript/gdscript_editor.cpp b/modules/gdscript/gdscript_editor.cpp index 26b14a6148..78a1bfc99b 100644 --- a/modules/gdscript/gdscript_editor.cpp +++ b/modules/gdscript/gdscript_editor.cpp @@ -509,12 +509,14 @@ struct GDScriptCompletionIdentifier { assigned_expression(NULL) {} }; -static void _get_directory_contents(EditorFileSystemDirectory *p_dir, Set<String> &r_list) { +static void _get_directory_contents(EditorFileSystemDirectory *p_dir, Map<String, ScriptCodeCompletionOption> &r_list) { const String quote_style = EDITOR_DEF("text_editor/completion/use_single_quotes", false) ? "'" : "\""; for (int i = 0; i < p_dir->get_file_count(); i++) { - r_list.insert(quote_style + p_dir->get_file_path(i) + quote_style); + ScriptCodeCompletionOption option(p_dir->get_file_path(i), ScriptCodeCompletionOption::KIND_FILE_PATH); + option.insert_text = quote_style + option.display + quote_style; + r_list.insert(option.display, option); } for (int i = 0; i < p_dir->get_subdir_count(); i++) { @@ -1807,14 +1809,15 @@ static String _make_arguments_hint(const GDScriptParser::FunctionNode *p_functio return arghint; } -static void _find_enumeration_candidates(const String p_enum_hint, Set<String> &r_result) { +static void _find_enumeration_candidates(const String p_enum_hint, Map<String, ScriptCodeCompletionOption> &r_result) { if (p_enum_hint.find(".") == -1) { // Global constant StringName current_enum = p_enum_hint; for (int i = 0; i < GlobalConstants::get_global_constant_count(); i++) { if (GlobalConstants::get_global_constant_enum(i) == current_enum) { - r_result.insert(GlobalConstants::get_global_constant_name(i)); + ScriptCodeCompletionOption option(GlobalConstants::get_global_constant_name(i), ScriptCodeCompletionOption::KIND_ENUM); + r_result.insert(option.display, option); } } } else { @@ -1829,15 +1832,17 @@ static void _find_enumeration_candidates(const String p_enum_hint, Set<String> & ClassDB::get_enum_constants(class_name, enum_name, &enum_constants); for (List<StringName>::Element *E = enum_constants.front(); E; E = E->next()) { String candidate = class_name + "." + E->get(); - r_result.insert(candidate); + ScriptCodeCompletionOption option(candidate, ScriptCodeCompletionOption::KIND_ENUM); + r_result.insert(option.display, option); } } } -static void _find_identifiers_in_block(const GDScriptCompletionContext &p_context, Set<String> &r_result) { +static void _find_identifiers_in_block(const GDScriptCompletionContext &p_context, Map<String, ScriptCodeCompletionOption> &r_result) { for (Map<StringName, GDScriptParser::LocalVarNode *>::Element *E = p_context.block->variables.front(); E; E = E->next()) { if (E->get()->line < p_context.line) { - r_result.insert(E->key().operator String()); + ScriptCodeCompletionOption option(E->key().operator String(), ScriptCodeCompletionOption::KIND_VARIABLE); + r_result.insert(option.display, option); } } if (p_context.block->parent_block) { @@ -1847,40 +1852,47 @@ static void _find_identifiers_in_block(const GDScriptCompletionContext &p_contex } } -static void _find_identifiers_in_base(const GDScriptCompletionContext &p_context, const GDScriptCompletionIdentifier &p_base, bool p_only_functions, Set<String> &r_result); +static void _find_identifiers_in_base(const GDScriptCompletionContext &p_context, const GDScriptCompletionIdentifier &p_base, bool p_only_functions, Map<String, ScriptCodeCompletionOption> &r_result); -static void _find_identifiers_in_class(const GDScriptCompletionContext &p_context, bool p_static, bool p_only_functions, bool p_parent_only, Set<String> &r_result) { +static void _find_identifiers_in_class(const GDScriptCompletionContext &p_context, bool p_static, bool p_only_functions, bool p_parent_only, Map<String, ScriptCodeCompletionOption> &r_result) { if (!p_parent_only) { if (!p_static && !p_only_functions) { for (int i = 0; i < p_context._class->variables.size(); i++) { - r_result.insert(p_context._class->variables[i].identifier); + ScriptCodeCompletionOption option(p_context._class->variables[i].identifier, ScriptCodeCompletionOption::KIND_MEMBER); + r_result.insert(option.display, option); } } if (!p_only_functions) { for (Map<StringName, GDScriptParser::ClassNode::Constant>::Element *E = p_context._class->constant_expressions.front(); E; E = E->next()) { - r_result.insert(E->key()); + ScriptCodeCompletionOption option(E->key(), ScriptCodeCompletionOption::KIND_CONSTANT); + r_result.insert(option.display, option); } for (int i = 0; i < p_context._class->subclasses.size(); i++) { - r_result.insert(p_context._class->subclasses[i]->name); + ScriptCodeCompletionOption option(p_context._class->subclasses[i]->name, ScriptCodeCompletionOption::KIND_CLASS); + r_result.insert(option.display, option); } } for (int i = 0; i < p_context._class->static_functions.size(); i++) { + ScriptCodeCompletionOption option(p_context._class->static_functions[i]->name.operator String(), ScriptCodeCompletionOption::KIND_FUNCTION); if (p_context._class->static_functions[i]->arguments.size()) { - r_result.insert(p_context._class->static_functions[i]->name.operator String() + "("); + option.insert_text += "("; } else { - r_result.insert(p_context._class->static_functions[i]->name.operator String() + "()"); + option.insert_text += "()"; } + r_result.insert(option.display, option); } if (!p_static) { for (int i = 0; i < p_context._class->functions.size(); i++) { + ScriptCodeCompletionOption option(p_context._class->functions[i]->name.operator String(), ScriptCodeCompletionOption::KIND_FUNCTION); if (p_context._class->functions[i]->arguments.size()) { - r_result.insert(p_context._class->functions[i]->name.operator String() + "("); + option.insert_text += "("; } else { - r_result.insert(p_context._class->functions[i]->name.operator String() + "()"); + option.insert_text += "()"; } + r_result.insert(option.display, option); } } } @@ -1898,12 +1910,14 @@ static void _find_identifiers_in_class(const GDScriptCompletionContext &p_contex _find_identifiers_in_base(c, base_type, p_only_functions, r_result); } -static void _find_identifiers_in_base(const GDScriptCompletionContext &p_context, const GDScriptCompletionIdentifier &p_base, bool p_only_functions, Set<String> &r_result) { +static void _find_identifiers_in_base(const GDScriptCompletionContext &p_context, const GDScriptCompletionIdentifier &p_base, bool p_only_functions, Map<String, ScriptCodeCompletionOption> &r_result) { GDScriptParser::DataType base_type = p_base.type; bool _static = base_type.is_meta_type; if (_static && base_type.kind != GDScriptParser::DataType::BUILTIN) { - r_result.insert("new("); + ScriptCodeCompletionOption option("new", ScriptCodeCompletionOption::KIND_FUNCTION); + option.insert_text += "("; + r_result.insert(option.display, option); } while (base_type.has_type) { @@ -1921,26 +1935,31 @@ static void _find_identifiers_in_base(const GDScriptCompletionContext &p_context if (script.is_valid()) { if (!_static && !p_only_functions) { for (const Set<StringName>::Element *E = script->get_members().front(); E; E = E->next()) { - r_result.insert(E->get().operator String()); + ScriptCodeCompletionOption option(E->get().operator String(), ScriptCodeCompletionOption::KIND_MEMBER); + r_result.insert(option.display, option); } } if (!p_only_functions) { for (const Map<StringName, Variant>::Element *E = script->get_constants().front(); E; E = E->next()) { - r_result.insert(E->key().operator String()); + ScriptCodeCompletionOption option(E->key().operator String(), ScriptCodeCompletionOption::KIND_CONSTANT); + r_result.insert(option.display, option); } } for (const Map<StringName, GDScriptFunction *>::Element *E = script->get_member_functions().front(); E; E = E->next()) { if (!_static || E->get()->is_static()) { + ScriptCodeCompletionOption option(E->key().operator String(), ScriptCodeCompletionOption::KIND_FUNCTION); if (E->get()->get_argument_count()) { - r_result.insert(E->key().operator String() + "("); + option.insert_text += "("; } else { - r_result.insert(E->key().operator String() + "()"); + option.insert_text += "()"; } + r_result.insert(option.display, option); } } if (!p_only_functions) { for (const Map<StringName, Ref<GDScript> >::Element *E = script->get_subclasses().front(); E; E = E->next()) { - r_result.insert(E->key().operator String()); + ScriptCodeCompletionOption option(E->key().operator String(), ScriptCodeCompletionOption::KIND_CLASS); + r_result.insert(option.display, option); } } base_type = GDScriptParser::DataType(); @@ -1964,25 +1983,29 @@ static void _find_identifiers_in_base(const GDScriptCompletionContext &p_context List<PropertyInfo> members; scr->get_script_property_list(&members); for (List<PropertyInfo>::Element *E = members.front(); E; E = E->next()) { - r_result.insert(E->get().name); + ScriptCodeCompletionOption option(E->get().name, ScriptCodeCompletionOption::KIND_MEMBER); + r_result.insert(option.display, option); } } if (!p_only_functions) { Map<StringName, Variant> constants; scr->get_constants(&constants); for (Map<StringName, Variant>::Element *E = constants.front(); E; E = E->next()) { - r_result.insert(E->key().operator String()); + ScriptCodeCompletionOption option(E->key().operator String(), ScriptCodeCompletionOption::KIND_CONSTANT); + r_result.insert(option.display, option); } } List<MethodInfo> methods; scr->get_script_method_list(&methods); for (List<MethodInfo>::Element *E = methods.front(); E; E = E->next()) { + ScriptCodeCompletionOption option(E->get().name, ScriptCodeCompletionOption::KIND_FUNCTION); if (E->get().arguments.size()) { - r_result.insert(E->get().name + "("); + option.insert_text += "("; } else { - r_result.insert(E->get().name + "()"); + option.insert_text += "()"; } + r_result.insert(option.display, option); } Ref<Script> base_script = scr->get_base_script(); @@ -2009,7 +2032,8 @@ static void _find_identifiers_in_base(const GDScriptCompletionContext &p_context List<String> constants; ClassDB::get_integer_constant_list(type, &constants); for (List<String>::Element *E = constants.front(); E; E = E->next()) { - r_result.insert(E->get()); + ScriptCodeCompletionOption option(E->get(), ScriptCodeCompletionOption::KIND_CONSTANT); + r_result.insert(option.display, option); } if (!_static) { @@ -2022,7 +2046,8 @@ static void _find_identifiers_in_base(const GDScriptCompletionContext &p_context if (E->get().name.find("/") != -1) { continue; } - r_result.insert(E->get().name); + ScriptCodeCompletionOption option(E->get().name, ScriptCodeCompletionOption::KIND_MEMBER); + r_result.insert(option.display, option); } } } @@ -2035,11 +2060,13 @@ static void _find_identifiers_in_base(const GDScriptCompletionContext &p_context if (E->get().name.begins_with("_")) { continue; } + ScriptCodeCompletionOption option(E->get().name, ScriptCodeCompletionOption::KIND_FUNCTION); if (E->get().arguments.size()) { - r_result.insert(E->get().name + "("); + option.insert_text += "("; } else { - r_result.insert(E->get().name + "()"); + option.insert_text += "()"; } + r_result.insert(option.display, option); } } @@ -2058,7 +2085,8 @@ static void _find_identifiers_in_base(const GDScriptCompletionContext &p_context for (List<PropertyInfo>::Element *E = members.front(); E; E = E->next()) { if (String(E->get().name).find("/") == -1) { - r_result.insert(E->get().name); + ScriptCodeCompletionOption option(E->get().name, ScriptCodeCompletionOption::KIND_MEMBER); + r_result.insert(option.display, option); } } } @@ -2066,11 +2094,13 @@ static void _find_identifiers_in_base(const GDScriptCompletionContext &p_context List<MethodInfo> methods; tmp.get_method_list(&methods); for (List<MethodInfo>::Element *E = methods.front(); E; E = E->next()) { + ScriptCodeCompletionOption option(E->get().name, ScriptCodeCompletionOption::KIND_FUNCTION); if (E->get().arguments.size()) { - r_result.insert(E->get().name + "("); + option.insert_text += "("; } else { - r_result.insert(E->get().name + "()"); + option.insert_text += "()"; } + r_result.insert(option.display, option); } return; @@ -2082,7 +2112,7 @@ static void _find_identifiers_in_base(const GDScriptCompletionContext &p_context } } -static void _find_identifiers(const GDScriptCompletionContext &p_context, bool p_only_functions, Set<String> &r_result) { +static void _find_identifiers(const GDScriptCompletionContext &p_context, bool p_only_functions, Map<String, ScriptCodeCompletionOption> &r_result) { const GDScriptParser::BlockNode *block = p_context.block; @@ -2091,7 +2121,8 @@ static void _find_identifiers(const GDScriptCompletionContext &p_context, bool p const GDScriptParser::FunctionNode *f = p_context.function; for (int i = 0; i < f->arguments.size(); i++) { - r_result.insert(f->arguments[i].operator String()); + ScriptCodeCompletionOption option(f->arguments[i].operator String(), ScriptCodeCompletionOption::KIND_PLAIN_TEXT); + r_result.insert(option.display, option); } } @@ -2116,11 +2147,13 @@ static void _find_identifiers(const GDScriptCompletionContext &p_context, bool p for (int i = 0; i < GDScriptFunctions::FUNC_MAX; i++) { MethodInfo mi = GDScriptFunctions::get_info(GDScriptFunctions::Function(i)); + ScriptCodeCompletionOption option(String(GDScriptFunctions::get_func_name(GDScriptFunctions::Function(i))), ScriptCodeCompletionOption::KIND_FUNCTION); if (mi.arguments.size() || (mi.flags & METHOD_FLAG_VARARG)) { - r_result.insert(String(GDScriptFunctions::get_func_name(GDScriptFunctions::Function(i))) + "("); + option.insert_text += "("; } else { - r_result.insert(String(GDScriptFunctions::get_func_name(GDScriptFunctions::Function(i))) + "()"); + option.insert_text += "()"; } + r_result.insert(option.display, option); } static const char *_type_names[Variant::VARIANT_MAX] = { @@ -2130,7 +2163,8 @@ static void _find_identifiers(const GDScriptCompletionContext &p_context, bool p }; for (int i = 0; i < Variant::VARIANT_MAX; i++) { - r_result.insert(_type_names[i]); + ScriptCodeCompletionOption option(_type_names[i], ScriptCodeCompletionOption::KIND_CLASS); + r_result.insert(option.display, option); } static const char *_keywords[] = { @@ -2144,7 +2178,8 @@ static void _find_identifiers(const GDScriptCompletionContext &p_context, bool p const char **kw = _keywords; while (*kw) { - r_result.insert(*kw); + ScriptCodeCompletionOption option(*kw, ScriptCodeCompletionOption::KIND_PLAIN_TEXT); + r_result.insert(option.display, option); kw++; } @@ -2158,7 +2193,8 @@ static void _find_identifiers(const GDScriptCompletionContext &p_context, bool p } String path = ProjectSettings::get_singleton()->get(s); if (path.begins_with("*")) { - r_result.insert(s.get_slice("/", 1)); + ScriptCodeCompletionOption option(s.get_slice("/", 1), ScriptCodeCompletionOption::KIND_CONSTANT); + r_result.insert(option.display, option); } } @@ -2166,16 +2202,18 @@ static void _find_identifiers(const GDScriptCompletionContext &p_context, bool p List<StringName> named_scripts; ScriptServer::get_global_class_list(&named_scripts); for (List<StringName>::Element *E = named_scripts.front(); E; E = E->next()) { - r_result.insert(E->get().operator String()); + ScriptCodeCompletionOption option(E->get().operator String(), ScriptCodeCompletionOption::KIND_CLASS); + r_result.insert(option.display, option); } // Native classes for (const Map<StringName, int>::Element *E = GDScriptLanguage::get_singleton()->get_global_map().front(); E; E = E->next()) { - r_result.insert(E->key().operator String()); + ScriptCodeCompletionOption option(E->key().operator String(), ScriptCodeCompletionOption::KIND_CLASS); + r_result.insert(option.display, option); } } -static void _find_call_arguments(const GDScriptCompletionContext &p_context, const GDScriptCompletionIdentifier &p_base, const StringName &p_method, int p_argidx, bool p_static, Set<String> &r_result, String &r_arghint) { +static void _find_call_arguments(const GDScriptCompletionContext &p_context, const GDScriptCompletionIdentifier &p_base, const StringName &p_method, int p_argidx, bool p_static, Map<String, ScriptCodeCompletionOption> &r_result, String &r_arghint) { Variant base = p_base.value; GDScriptParser::DataType base_type = p_base.type; @@ -2199,7 +2237,9 @@ static void _find_call_arguments(const GDScriptCompletionContext &p_context, con if ((p_method == "connect" || p_method == "emit_signal") && p_argidx == 0) { for (int i = 0; i < base_type.class_type->_signals.size(); i++) { - r_result.insert(quote_style + base_type.class_type->_signals[i].name.operator String() + quote_style); + ScriptCodeCompletionOption option(base_type.class_type->_signals[i].name.operator String(), ScriptCodeCompletionOption::KIND_SIGNAL); + option.insert_text = quote_style + option.display + quote_style; + r_result.insert(option.display, option); } } @@ -2212,7 +2252,9 @@ static void _find_call_arguments(const GDScriptCompletionContext &p_context, con List<MethodInfo> signals; gds->get_script_signal_list(&signals); for (List<MethodInfo>::Element *E = signals.front(); E; E = E->next()) { - r_result.insert(quote_style + E->get().name + quote_style); + ScriptCodeCompletionOption option(E->get().name, ScriptCodeCompletionOption::KIND_SIGNAL); + option.insert_text = quote_style + option.display + quote_style; + r_result.insert(option.display, option); } } Ref<GDScript> base_script = gds->get_base_script(); @@ -2250,7 +2292,8 @@ static void _find_call_arguments(const GDScriptCompletionContext &p_context, con List<String> options; obj->get_argument_options(p_method, p_argidx, &options); for (List<String>::Element *F = options.front(); F; F = F->next()) { - r_result.insert(F->get()); + ScriptCodeCompletionOption option(F->get(), ScriptCodeCompletionOption::KIND_FUNCTION); + r_result.insert(option.display, option); } } } @@ -2271,7 +2314,9 @@ static void _find_call_arguments(const GDScriptCompletionContext &p_context, con List<MethodInfo> signals; ClassDB::get_signal_list(class_name, &signals); for (List<MethodInfo>::Element *E = signals.front(); E; E = E->next()) { - r_result.insert(quote_style + E->get().name + quote_style); + ScriptCodeCompletionOption option(E->get().name, ScriptCodeCompletionOption::KIND_SIGNAL); + option.insert_text = quote_style + option.display + quote_style; + r_result.insert(option.display, option); } } @@ -2286,7 +2331,9 @@ static void _find_call_arguments(const GDScriptCompletionContext &p_context, con continue; } String name = s.get_slice("/", 1); - r_result.insert(quote_style + "/root/" + name + quote_style); + ScriptCodeCompletionOption option("/root/" + name, ScriptCodeCompletionOption::KIND_NODE_PATH); + option.insert_text = quote_style + option.display + quote_style; + r_result.insert(option.display, option); } } @@ -2300,7 +2347,9 @@ static void _find_call_arguments(const GDScriptCompletionContext &p_context, con continue; } String name = s.get_slice("/", 1); - r_result.insert(quote_style + name + quote_style); + ScriptCodeCompletionOption option(name, ScriptCodeCompletionOption::KIND_CONSTANT); + option.insert_text = quote_style + option.display + quote_style; + r_result.insert(option.display, option); } } @@ -2333,7 +2382,7 @@ static void _find_call_arguments(const GDScriptCompletionContext &p_context, con } } -static void _find_call_arguments(GDScriptCompletionContext &p_context, const GDScriptParser::Node *p_node, int p_argidx, Set<String> &r_result, bool &r_forced, String &r_arghint) { +static void _find_call_arguments(GDScriptCompletionContext &p_context, const GDScriptParser::Node *p_node, int p_argidx, Map<String, ScriptCodeCompletionOption> &r_result, bool &r_forced, String &r_arghint) { const String quote_style = EDITOR_DEF("text_editor/completion/use_single_quotes", false) ? "'" : "\""; @@ -2451,17 +2500,19 @@ static void _find_call_arguments(GDScriptCompletionContext &p_context, const GDS _find_call_arguments(p_context, ci, function, p_argidx, _static, r_result, r_arghint); if (function == "connect" && p_argidx == 2) { - Set<String> methods; + Map<String, ScriptCodeCompletionOption> methods; _find_identifiers_in_base(p_context, connect_base, true, methods); - for (Set<String>::Element *E = methods.front(); E; E = E->next()) { - r_result.insert(quote_style + E->get().replace("(", "").replace(")", "") + quote_style); + for (Map<String, ScriptCodeCompletionOption>::Element *E = methods.front(); E; E = E->next()) { + ScriptCodeCompletionOption &option = E->value(); + option.insert_text = quote_style + option.display + quote_style; + r_result.insert(option.display, option); } } r_forced = r_result.size() > 0; } -Error GDScriptLanguage::complete_code(const String &p_code, const String &p_path, Object *p_owner, List<String> *r_options, bool &r_forced, String &r_call_hint) { +Error GDScriptLanguage::complete_code(const String &p_code, const String &p_path, Object *p_owner, List<ScriptCodeCompletionOption> *r_options, bool &r_forced, String &r_call_hint) { const String quote_style = EDITOR_DEF("text_editor/completion/use_single_quotes", false) ? "'" : "\""; @@ -2469,7 +2520,7 @@ Error GDScriptLanguage::complete_code(const String &p_code, const String &p_path parser.parse(p_code, p_path.get_base_dir(), false, p_path, true); r_forced = false; - Set<String> options; + Map<String, ScriptCodeCompletionOption> options; GDScriptCompletionContext context; context._class = parser.get_completion_class(); context.block = parser.get_completion_block(); @@ -2490,7 +2541,8 @@ Error GDScriptLanguage::complete_code(const String &p_code, const String &p_path List<StringName> constants; Variant::get_constants_for_type(parser.get_completion_built_in_constant(), &constants); for (List<StringName>::Element *E = constants.front(); E; E = E->next()) { - options.insert(E->get().operator String()); + ScriptCodeCompletionOption option(E->get().operator String(), ScriptCodeCompletionOption::KIND_CONSTANT); + options.insert(option.display, option); } } break; case GDScriptParser::COMPLETION_PARENT_FUNCTION: { @@ -2515,9 +2567,11 @@ Error GDScriptLanguage::complete_code(const String &p_code, const String &p_path r_forced = true; String idopt = opt.unquote(); if (idopt.replace("/", "_").is_valid_identifier()) { - options.insert(idopt); + ScriptCodeCompletionOption option(idopt, ScriptCodeCompletionOption::KIND_NODE_PATH); + options.insert(option.display, option); } else { - options.insert(opt); + ScriptCodeCompletionOption option(opt, ScriptCodeCompletionOption::KIND_NODE_PATH); + options.insert(option.display, option); } } } @@ -2532,7 +2586,8 @@ Error GDScriptLanguage::complete_code(const String &p_code, const String &p_path continue; } String name = s.get_slice("/", 1); - options.insert(quote_style + "/root/" + name + quote_style); + ScriptCodeCompletionOption option(quote_style + "/root/" + name + quote_style, ScriptCodeCompletionOption::KIND_NODE_PATH); + options.insert(option.display, option); } } } break; @@ -2655,7 +2710,8 @@ Error GDScriptLanguage::complete_code(const String &p_code, const String &p_path } method_hint += ":"; - options.insert(method_hint); + ScriptCodeCompletionOption option(method_hint, ScriptCodeCompletionOption::KIND_FUNCTION); + options.insert(option.display, option); } } break; case GDScriptParser::COMPLETION_YIELD: { @@ -2673,7 +2729,9 @@ Error GDScriptLanguage::complete_code(const String &p_code, const String &p_path switch (base_type.kind) { case GDScriptParser::DataType::CLASS: { for (int i = 0; i < base_type.class_type->_signals.size(); i++) { - options.insert(quote_style + base_type.class_type->_signals[i].name.operator String() + quote_style); + ScriptCodeCompletionOption option(base_type.class_type->_signals[i].name.operator String(), ScriptCodeCompletionOption::KIND_SIGNAL); + option.insert_text = quote_style + option.display + quote_style; + options.insert(option.display, option); } base_type = base_type.class_type->base_type; } break; @@ -2684,7 +2742,8 @@ Error GDScriptLanguage::complete_code(const String &p_code, const String &p_path List<MethodInfo> signals; scr->get_script_signal_list(&signals); for (List<MethodInfo>::Element *E = signals.front(); E; E = E->next()) { - options.insert(quote_style + E->get().name + quote_style); + ScriptCodeCompletionOption option(quote_style + E->get().name + quote_style, ScriptCodeCompletionOption::KIND_SIGNAL); + options.insert(option.display, option); } Ref<Script> base_script = scr->get_base_script(); if (base_script.is_valid()) { @@ -2711,7 +2770,8 @@ Error GDScriptLanguage::complete_code(const String &p_code, const String &p_path List<MethodInfo> signals; ClassDB::get_signal_list(class_name, &signals); for (List<MethodInfo>::Element *E = signals.front(); E; E = E->next()) { - options.insert(quote_style + E->get().name + quote_style); + ScriptCodeCompletionOption option(quote_style + E->get().name + quote_style, ScriptCodeCompletionOption::KIND_SIGNAL); + options.insert(option.display, option); } } break; default: { @@ -2748,18 +2808,21 @@ Error GDScriptLanguage::complete_code(const String &p_code, const String &p_path c.line = E->value().expression->line; if (_guess_expression_type(c, E->value().expression, constant)) { if (constant.type.has_type && constant.type.is_meta_type) { - options.insert(E->key().operator String()); + ScriptCodeCompletionOption option(E->key().operator String(), ScriptCodeCompletionOption::KIND_CLASS); + options.insert(option.display, option); } } } for (int i = 0; i < clss->subclasses.size(); i++) { if (clss->subclasses[i]->name != StringName()) { - options.insert(clss->subclasses[i]->name.operator String()); + ScriptCodeCompletionOption option(clss->subclasses[i]->name.operator String(), ScriptCodeCompletionOption::KIND_CLASS); + options.insert(option.display, option); } } clss = clss->owner; for (int i = 0; i < Variant::VARIANT_MAX; i++) { - options.insert(Variant::get_type_name((Variant::Type)i)); + ScriptCodeCompletionOption option(Variant::get_type_name((Variant::Type)i), ScriptCodeCompletionOption::KIND_CLASS); + options.insert(option.display, option); } } @@ -2773,18 +2836,21 @@ Error GDScriptLanguage::complete_code(const String &p_code, const String &p_path if (Engine::get_singleton()->has_singleton(class_name)) { continue; } - options.insert(class_name); + ScriptCodeCompletionOption option(class_name, ScriptCodeCompletionOption::KIND_CLASS); + options.insert(option.display, option); } // Named scripts List<StringName> named_scripts; ScriptServer::get_global_class_list(&named_scripts); for (List<StringName>::Element *E = named_scripts.front(); E; E = E->next()) { - options.insert(E->get().operator String()); + ScriptCodeCompletionOption option(E->get().operator String(), ScriptCodeCompletionOption::KIND_CLASS); + options.insert(option.display, option); } if (parser.get_completion_identifier_is_function()) { - options.insert("void"); + ScriptCodeCompletionOption option("void", ScriptCodeCompletionOption::KIND_PLAIN_TEXT); + options.insert(option.display, option); } r_forced = true; } break; @@ -2831,13 +2897,15 @@ Error GDScriptLanguage::complete_code(const String &p_code, const String &p_path c2.line = E->value().expression->line; if (_guess_expression_type(c2, E->value().expression, constant)) { if (constant.type.has_type && constant.type.is_meta_type) { - options.insert(E->key().operator String()); + ScriptCodeCompletionOption option(E->key().operator String(), ScriptCodeCompletionOption::KIND_CLASS); + options.insert(option.display, option); } } } for (int i = 0; i < base_type.class_type->subclasses.size(); i++) { if (base_type.class_type->subclasses[i]->name != StringName()) { - options.insert(base_type.class_type->subclasses[i]->name.operator String()); + ScriptCodeCompletionOption option(base_type.class_type->subclasses[i]->name.operator String(), ScriptCodeCompletionOption::KIND_CLASS); + options.insert(option.display, option); } } @@ -2855,7 +2923,8 @@ Error GDScriptLanguage::complete_code(const String &p_code, const String &p_path for (Map<StringName, Variant>::Element *E = constants.front(); E; E = E->next()) { Ref<Script> const_scr = E->value(); if (const_scr.is_valid()) { - options.insert(E->key().operator String()); + ScriptCodeCompletionOption option(E->key().operator String(), ScriptCodeCompletionOption::KIND_CLASS); + options.insert(option.display, option); } } Ref<Script> base_script = scr->get_base_script(); @@ -2877,7 +2946,7 @@ Error GDScriptLanguage::complete_code(const String &p_code, const String &p_path } break; } - for (Set<String>::Element *E = options.front(); E; E = E->next()) { + for (Map<String, ScriptCodeCompletionOption>::Element *E = options.front(); E; E = E->next()) { r_options->push_back(E->get()); } @@ -2886,7 +2955,7 @@ Error GDScriptLanguage::complete_code(const String &p_code, const String &p_path #else -Error GDScriptLanguage::complete_code(const String &p_code, const String &p_path, Object *p_owner, List<String> *r_options, bool &r_forced, String &r_call_hint) { +Error GDScriptLanguage::complete_code(const String &p_code, const String &p_path, Object *p_owner, List<ScriptCodeCompletionOption> *r_options, bool &r_forced, String &r_call_hint) { return OK; } diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp index 9ab86a5459..c5c86fda0a 100644 --- a/modules/gdscript/gdscript_parser.cpp +++ b/modules/gdscript/gdscript_parser.cpp @@ -125,7 +125,7 @@ bool GDScriptParser::_enter_indent_block(BlockNode *p_block) { } } -bool GDScriptParser::_parse_arguments(Node *p_parent, Vector<Node *> &p_args, bool p_static, bool p_can_codecomplete) { +bool GDScriptParser::_parse_arguments(Node *p_parent, Vector<Node *> &p_args, bool p_static, bool p_can_codecomplete, bool p_parsing_constant) { if (tokenizer->get_token() == GDScriptTokenizer::TK_PARENTHESIS_CLOSE) { tokenizer->advance(); @@ -149,7 +149,7 @@ bool GDScriptParser::_parse_arguments(Node *p_parent, Vector<Node *> &p_args, bo return false; } - Node *arg = _parse_expression(p_parent, p_static); + Node *arg = _parse_expression(p_parent, p_static, false, p_parsing_constant); if (!arg) { return false; } @@ -639,7 +639,7 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s id->name = identifier; op->arguments.push_back(id); - if (!_parse_arguments(op, op->arguments, p_static, true)) + if (!_parse_arguments(op, op->arguments, p_static, true, p_parsing_constant)) return NULL; expr = op; @@ -731,7 +731,7 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s completion_node = op; } if (!replaced) { - if (!_parse_arguments(op, op->arguments, p_static, true)) + if (!_parse_arguments(op, op->arguments, p_static, true, p_parsing_constant)) return NULL; expr = op; } @@ -826,11 +826,12 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s } // Check parents for the constant - if (!bfn && cln->extends_file != StringName()) { - Ref<GDScript> parent = ResourceLoader::load(cln->extends_file); - if (parent.is_valid() && parent->is_valid()) { + if (!bfn) { + // Using current_class instead of cln here, since cln is const* + _determine_inheritance(current_class, false); + if (cln->base_type.has_type && cln->base_type.kind == DataType::GDSCRIPT && cln->base_type.script_type->is_valid()) { Map<StringName, Variant> parent_constants; - parent->get_constants(&parent_constants); + current_class->base_type.script_type->get_constants(&parent_constants); if (parent_constants.has(identifier)) { ConstantNode *constant = alloc_node<ConstantNode>(); constant->value = parent_constants[identifier]; @@ -1112,7 +1113,7 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s } } else { tokenizer->advance(); - if (!_parse_arguments(op, op->arguments, p_static)) { + if (!_parse_arguments(op, op->arguments, p_static, false, p_parsing_constant)) { return NULL; } } @@ -1164,22 +1165,14 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s tokenizer->advance(); IdentifierNode *id = alloc_node<IdentifierNode>(); - if (tokenizer->get_token() == GDScriptTokenizer::TK_BUILT_IN_FUNC) { - //small hack so built in funcs don't obfuscate methods - - id->name = GDScriptFunctions::get_func_name(tokenizer->get_token_built_in_func()); - tokenizer->advance(); - - } else { - StringName identifier; - if (_get_completable_identifier(COMPLETION_METHOD, identifier)) { - completion_node = op; - //indexing stuff - } - - id->name = identifier; + StringName identifier; + if (_get_completable_identifier(COMPLETION_METHOD, identifier)) { + completion_node = op; + //indexing stuff } + id->name = identifier; + op->arguments.push_back(expr); // call what op->arguments.push_back(id); // call func //get arguments @@ -1188,7 +1181,7 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s _make_completable_call(0); completion_node = op; } - if (!_parse_arguments(op, op->arguments, p_static, true)) + if (!_parse_arguments(op, op->arguments, p_static, true, p_parsing_constant)) return NULL; expr = op; @@ -5158,9 +5151,11 @@ void GDScriptParser::_parse_class(ClassNode *p_class) { } } -void GDScriptParser::_determine_inheritance(ClassNode *p_class) { +void GDScriptParser::_determine_inheritance(ClassNode *p_class, bool p_recursive) { - if (p_class->extends_used) { + if (p_class->base_type.has_type) { + // Already determined + } else if (p_class->extends_used) { //do inheritance String path = p_class->extends_file; @@ -5355,9 +5350,11 @@ void GDScriptParser::_determine_inheritance(ClassNode *p_class) { p_class->base_type.native_type = "Reference"; } - // Recursively determine subclasses - for (int i = 0; i < p_class->subclasses.size(); i++) { - _determine_inheritance(p_class->subclasses[i]); + if (p_recursive) { + // Recursively determine subclasses + for (int i = 0; i < p_class->subclasses.size(); i++) { + _determine_inheritance(p_class->subclasses[i], p_recursive); + } } } diff --git a/modules/gdscript/gdscript_parser.h b/modules/gdscript/gdscript_parser.h index 5e4de11357..62d7bdb393 100644 --- a/modules/gdscript/gdscript_parser.h +++ b/modules/gdscript/gdscript_parser.h @@ -582,7 +582,7 @@ private: #endif // DEBUG_ENABLED bool _recover_from_completion(); - bool _parse_arguments(Node *p_parent, Vector<Node *> &p_args, bool p_static, bool p_can_codecomplete = false); + bool _parse_arguments(Node *p_parent, Vector<Node *> &p_args, bool p_static, bool p_can_codecomplete = false, bool p_parsing_constant = false); bool _enter_indent_block(BlockNode *p_block = NULL); bool _parse_newline(); Node *_parse_expression(Node *p_parent, bool p_static, bool p_allow_assign = false, bool p_parsing_constant = false); @@ -599,7 +599,7 @@ private: void _parse_class(ClassNode *p_class); bool _end_statement(); - void _determine_inheritance(ClassNode *p_class); + void _determine_inheritance(ClassNode *p_class, bool p_recursive = true); bool _parse_type(DataType &r_type, bool p_can_be_void = false); DataType _resolve_type(const DataType &p_source, int p_line); DataType _type_from_variant(const Variant &p_value) const; |