Browse Source

Merge pull request #24925 from Mr-Slurpy/typed-autoload

Added autoloads as a potential type.
Rémi Verschelde 6 years ago
parent
commit
877912b23c
2 changed files with 76 additions and 2 deletions
  1. 9 0
      modules/gdscript/gdscript_editor.cpp
  2. 67 2
      modules/gdscript/gdscript_parser.cpp

+ 9 - 0
modules/gdscript/gdscript_editor.cpp

@@ -2826,6 +2826,15 @@ Error GDScriptLanguage::complete_code(const String &p_code, const String &p_path
 					ScriptCodeCompletionOption option(Variant::get_type_name((Variant::Type)i), ScriptCodeCompletionOption::KIND_CLASS);
 					options.insert(option.display, option);
 				}
+				List<PropertyInfo> props;
+				ProjectSettings::get_singleton()->get_property_list(&props);
+				for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) {
+					String s = E->get().name;
+					if (!s.begins_with("autoload/")) {
+						continue;
+					}
+					options.insert(s.get_slice("/", 1));
+				}
 			}
 
 			List<StringName> native_classes;

+ 67 - 2
modules/gdscript/gdscript_parser.cpp

@@ -5245,6 +5245,31 @@ void GDScriptParser::_determine_inheritance(ClassNode *p_class, bool p_recursive
 					return;
 				}
 				p = NULL;
+			} else {
+				List<PropertyInfo> props;
+				ProjectSettings::get_singleton()->get_property_list(&props);
+				for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) {
+					String s = E->get().name;
+					if (!s.begins_with("autoload/")) {
+						continue;
+					}
+					String name = s.get_slice("/", 1);
+					if (name == base) {
+						String singleton_path = ProjectSettings::get_singleton()->get(s);
+						if (singleton_path.begins_with("*")) {
+							singleton_path = singleton_path.right(1);
+						}
+						if (!singleton_path.begins_with("res://")) {
+							singleton_path = "res://" + singleton_path;
+						}
+						base_script = ResourceLoader::load(singleton_path);
+						if (!base_script.is_valid()) {
+							_set_error("Class '" + base + "' could not be fully loaded (script error or cyclic inheritance).", p_class->line);
+							return;
+						}
+						p = NULL;
+					}
+				}
 			}
 
 			while (p) {
@@ -5589,9 +5614,49 @@ GDScriptParser::DataType GDScriptParser::_resolve_type(const DataType &p_source,
 				}
 				name_part++;
 				continue;
-			} else {
-				p = current_class;
 			}
+			List<PropertyInfo> props;
+			ProjectSettings::get_singleton()->get_property_list(&props);
+			String singleton_path;
+			for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) {
+				String s = E->get().name;
+				if (!s.begins_with("autoload/")) {
+					continue;
+				}
+				String name = s.get_slice("/", 1);
+				if (name == id) {
+					singleton_path = ProjectSettings::get_singleton()->get(s);
+					if (singleton_path.begins_with("*")) {
+						singleton_path = singleton_path.right(1);
+					}
+					if (!singleton_path.begins_with("res://")) {
+						singleton_path = "res://" + singleton_path;
+					}
+					break;
+				}
+			}
+			if (!singleton_path.empty()) {
+				Ref<Script> script = ResourceLoader::load(singleton_path);
+				Ref<GDScript> gds = script;
+				if (gds.is_valid()) {
+					if (!gds->is_valid()) {
+						_set_error("Class '" + id + "' could not be fully loaded (script error or cyclic inheritance).", p_line);
+						return DataType();
+					}
+					result.kind = DataType::GDSCRIPT;
+					result.script_type = gds;
+				} else if (script.is_valid()) {
+					result.kind = DataType::SCRIPT;
+					result.script_type = script;
+				} else {
+					_set_error("Couldn't fully load singleton script '" + id + "' (possible cyclic reference or parse error).", p_line);
+					return DataType();
+				}
+				name_part++;
+				continue;
+			}
+
+			p = current_class;
 		} else if (base_type.kind == DataType::CLASS) {
 			p = base_type.class_type;
 		}