summaryrefslogtreecommitdiffstats
path: root/modules/gdscript/gdscript_editor.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'modules/gdscript/gdscript_editor.cpp')
-rw-r--r--modules/gdscript/gdscript_editor.cpp74
1 files changed, 63 insertions, 11 deletions
diff --git a/modules/gdscript/gdscript_editor.cpp b/modules/gdscript/gdscript_editor.cpp
index babd2c1772..74d383c57f 100644
--- a/modules/gdscript/gdscript_editor.cpp
+++ b/modules/gdscript/gdscript_editor.cpp
@@ -163,7 +163,7 @@ bool GDScriptLanguage::validate(const String &p_script, const String &p_path, Li
r_errors->push_back(e);
}
- for (KeyValue<String, Ref<GDScriptParserRef>> E : analyzer.get_depended_parsers()) {
+ for (KeyValue<String, Ref<GDScriptParserRef>> E : parser.get_depended_parsers()) {
GDScriptParser *depended_parser = E.value->get_parser();
for (const GDScriptParser::ParserError &pe : depended_parser->get_errors()) {
ScriptLanguage::ScriptError e;
@@ -651,6 +651,21 @@ static int _get_enum_constant_location(const StringName &p_class, const StringNa
return depth | ScriptLanguage::LOCATION_PARENT_MASK;
}
+static int _get_enum_location(const StringName &p_class, const StringName &p_enum) {
+ if (!ClassDB::has_enum(p_class, p_enum)) {
+ return ScriptLanguage::LOCATION_OTHER;
+ }
+
+ int depth = 0;
+ StringName class_test = p_class;
+ while (class_test && !ClassDB::has_enum(class_test, p_enum, true)) {
+ class_test = ClassDB::get_parent_class(class_test);
+ depth++;
+ }
+
+ return depth | ScriptLanguage::LOCATION_PARENT_MASK;
+}
+
// END LOCATION METHODS
static String _trim_parent_class(const String &p_class, const String &p_base_class) {
@@ -828,17 +843,21 @@ static String _make_arguments_hint(const GDScriptParser::FunctionNode *p_functio
return arghint;
}
-static void _get_directory_contents(EditorFileSystemDirectory *p_dir, HashMap<String, ScriptLanguage::CodeCompletionOption> &r_list) {
+static void _get_directory_contents(EditorFileSystemDirectory *p_dir, HashMap<String, ScriptLanguage::CodeCompletionOption> &r_list, const StringName &p_required_type = StringName()) {
const String quote_style = EDITOR_GET("text_editor/completion/use_single_quotes") ? "'" : "\"";
+ const bool requires_type = p_required_type;
for (int i = 0; i < p_dir->get_file_count(); i++) {
+ if (requires_type && !ClassDB::is_parent_class(p_dir->get_file_type(i), p_required_type)) {
+ continue;
+ }
ScriptLanguage::CodeCompletionOption option(p_dir->get_file_path(i), ScriptLanguage::CODE_COMPLETION_KIND_FILE_PATH);
option.insert_text = option.display.quote(quote_style);
r_list.insert(option.display, option);
}
for (int i = 0; i < p_dir->get_subdir_count(); i++) {
- _get_directory_contents(p_dir->get_subdir(i), r_list);
+ _get_directory_contents(p_dir->get_subdir(i), r_list, p_required_type);
}
}
@@ -1198,13 +1217,15 @@ static void _find_identifiers_in_base(const GDScriptCompletionIdentifier &p_base
return;
}
+ List<StringName> enums;
+ ClassDB::get_enum_list(type, &enums);
+ for (const StringName &E : enums) {
+ int location = p_recursion_depth + _get_enum_location(type, E);
+ ScriptLanguage::CodeCompletionOption option(E, ScriptLanguage::CODE_COMPLETION_KIND_ENUM, location);
+ r_result.insert(option.display, option);
+ }
+
if (p_types_only) {
- List<StringName> enums;
- ClassDB::get_enum_list(type, &enums);
- for (const StringName &E : enums) {
- ScriptLanguage::CodeCompletionOption option(E, ScriptLanguage::CODE_COMPLETION_KIND_ENUM);
- r_result.insert(option.display, option);
- }
return;
}
@@ -1264,7 +1285,20 @@ static void _find_identifiers_in_base(const GDScriptCompletionIdentifier &p_base
}
return;
} break;
- case GDScriptParser::DataType::ENUM:
+ case GDScriptParser::DataType::ENUM: {
+ String type_str = base_type.native_type;
+ StringName type = type_str.get_slicec('.', 0);
+ StringName type_enum = base_type.enum_type;
+
+ List<StringName> enum_values;
+ ClassDB::get_enum_constants(type, type_enum, &enum_values);
+ for (const StringName &E : enum_values) {
+ int location = p_recursion_depth + _get_enum_constant_location(type, E);
+ ScriptLanguage::CodeCompletionOption option(E, ScriptLanguage::CODE_COMPLETION_KIND_CONSTANT, location);
+ r_result.insert(option.display, option);
+ }
+ }
+ [[fallthrough]];
case GDScriptParser::DataType::BUILTIN: {
if (p_types_only) {
return;
@@ -2661,6 +2695,8 @@ static void _find_call_arguments(GDScriptParser::CompletionContext &p_context, c
GDScriptParser::DataType base_type = p_base.type;
const String quote_style = EDITOR_GET("text_editor/completion/use_single_quotes") ? "'" : "\"";
+ const bool use_string_names = EDITOR_GET("text_editor/completion/add_string_name_literals");
+ const bool use_node_paths = EDITOR_GET("text_editor/completion/add_node_path_literals");
while (base_type.is_set() && !base_type.is_variant()) {
switch (base_type.kind) {
@@ -2694,8 +2730,14 @@ static void _find_call_arguments(GDScriptParser::CompletionContext &p_context, c
List<String> options;
obj->get_argument_options(p_method, p_argidx, &options);
for (String &opt : options) {
+ // Handle user preference.
if (opt.is_quoted()) {
- opt = opt.unquote().quote(quote_style); // Handle user preference.
+ opt = opt.unquote().quote(quote_style);
+ if (use_string_names && info.arguments[p_argidx].type == Variant::STRING_NAME) {
+ opt = opt.indent("&");
+ } else if (use_node_paths && info.arguments[p_argidx].type == Variant::NODE_PATH) {
+ opt = opt.indent("^");
+ }
}
ScriptLanguage::CodeCompletionOption option(opt, ScriptLanguage::CODE_COMPLETION_KIND_FUNCTION);
r_result.insert(option.display, option);
@@ -2803,6 +2845,16 @@ static void _find_call_arguments(GDScriptParser::CompletionContext &p_context, c
r_result.insert(option.display, option);
}
}
+ if (EDITOR_GET("text_editor/completion/complete_file_paths")) {
+ if (p_argidx == 0 && p_method == SNAME("change_scene_to_file") && ClassDB::is_parent_class(class_name, SNAME("SceneTree"))) {
+ HashMap<String, ScriptLanguage::CodeCompletionOption> list;
+ _get_directory_contents(EditorFileSystem::get_singleton()->get_filesystem(), list, SNAME("PackedScene"));
+ for (const KeyValue<String, ScriptLanguage::CodeCompletionOption> &key_value_pair : list) {
+ ScriptLanguage::CodeCompletionOption option = key_value_pair.value;
+ r_result.insert(option.display, option);
+ }
+ }
+ }
base_type.kind = GDScriptParser::DataType::UNRESOLVED;
} break;