瀏覽代碼

Handle GDScript in `_type_from_variant` for autocompletion

HolonProduction 1 年之前
父節點
當前提交
6af45c6ef2
共有 1 個文件被更改,包括 30 次插入16 次删除
  1. 30 16
      modules/gdscript/gdscript_editor.cpp

+ 30 - 16
modules/gdscript/gdscript_editor.cpp

@@ -1370,7 +1370,7 @@ static void _find_identifiers(const GDScriptParser::CompletionContext &p_context
 	}
 }
 
-static GDScriptCompletionIdentifier _type_from_variant(const Variant &p_value) {
+static GDScriptCompletionIdentifier _type_from_variant(const Variant &p_value, GDScriptParser::CompletionContext &p_context) {
 	GDScriptCompletionIdentifier ci;
 	ci.value = p_value;
 	ci.type.is_constant = true;
@@ -1392,8 +1392,22 @@ static GDScriptCompletionIdentifier _type_from_variant(const Variant &p_value) {
 			scr = obj->get_script();
 		}
 		if (scr.is_valid()) {
-			ci.type.script_type = scr;
+			ci.type.script_path = scr->get_path();
+
+			if (scr->get_path().ends_with(".gd")) {
+				Error err;
+				Ref<GDScriptParserRef> parser = GDScriptCache::get_parser(scr->get_path(), GDScriptParserRef::INTERFACE_SOLVED, err);
+				if (err == OK) {
+					ci.type.type_source = GDScriptParser::DataType::ANNOTATED_EXPLICIT;
+					ci.type.class_type = parser->get_parser()->get_tree();
+					ci.type.kind = GDScriptParser::DataType::CLASS;
+					p_context.dependent_parsers.push_back(parser);
+					return ci;
+				}
+			}
+
 			ci.type.kind = GDScriptParser::DataType::SCRIPT;
+			ci.type.script_type = scr;
 			ci.type.native_type = scr->get_instance_base_type();
 		} else {
 			ci.type.kind = GDScriptParser::DataType::NATIVE;
@@ -1481,7 +1495,7 @@ static bool _guess_expression_type(GDScriptParser::CompletionContext &p_context,
 
 	if (p_expression->is_constant) {
 		// Already has a value, so just use that.
-		r_type = _type_from_variant(p_expression->reduced_value);
+		r_type = _type_from_variant(p_expression->reduced_value, p_context);
 		switch (p_expression->get_datatype().kind) {
 			case GDScriptParser::DataType::ENUM:
 			case GDScriptParser::DataType::CLASS:
@@ -1495,7 +1509,7 @@ static bool _guess_expression_type(GDScriptParser::CompletionContext &p_context,
 		switch (p_expression->type) {
 			case GDScriptParser::Node::LITERAL: {
 				const GDScriptParser::LiteralNode *literal = static_cast<const GDScriptParser::LiteralNode *>(p_expression);
-				r_type = _type_from_variant(literal->value);
+				r_type = _type_from_variant(literal->value, p_context);
 				found = true;
 			} break;
 			case GDScriptParser::Node::SELF: {
@@ -1676,7 +1690,7 @@ static bool _guess_expression_type(GDScriptParser::CompletionContext &p_context,
 										if (!which.is_empty()) {
 											// Try singletons first
 											if (GDScriptLanguage::get_singleton()->get_named_globals_map().has(which)) {
-												r_type = _type_from_variant(GDScriptLanguage::get_singleton()->get_named_globals_map()[which]);
+												r_type = _type_from_variant(GDScriptLanguage::get_singleton()->get_named_globals_map()[which], p_context);
 												found = true;
 											} else {
 												for (const KeyValue<StringName, ProjectSettings::AutoloadInfo> &E : ProjectSettings::get_singleton()->get_autoload_list()) {
@@ -1727,7 +1741,7 @@ static bool _guess_expression_type(GDScriptParser::CompletionContext &p_context,
 
 									if (ce.error == Callable::CallError::CALL_OK && ret.get_type() != Variant::NIL) {
 										if (ret.get_type() != Variant::OBJECT || ret.operator Object *() != nullptr) {
-											r_type = _type_from_variant(ret);
+											r_type = _type_from_variant(ret, p_context);
 											found = true;
 										}
 									}
@@ -1755,7 +1769,7 @@ static bool _guess_expression_type(GDScriptParser::CompletionContext &p_context,
 
 					if (base.value.get_type() == Variant::DICTIONARY && base.value.operator Dictionary().has(String(subscript->attribute->name))) {
 						Variant value = base.value.operator Dictionary()[String(subscript->attribute->name)];
-						r_type = _type_from_variant(value);
+						r_type = _type_from_variant(value, p_context);
 						found = true;
 						break;
 					}
@@ -1807,7 +1821,7 @@ static bool _guess_expression_type(GDScriptParser::CompletionContext &p_context,
 
 					if (base.value.in(index.value)) {
 						Variant value = base.value.get(index.value);
-						r_type = _type_from_variant(value);
+						r_type = _type_from_variant(value, p_context);
 						found = true;
 						break;
 					}
@@ -1862,7 +1876,7 @@ static bool _guess_expression_type(GDScriptParser::CompletionContext &p_context,
 						bool valid = false;
 						Variant res = base_val.get(index.value, &valid);
 						if (valid) {
-							r_type = _type_from_variant(res);
+							r_type = _type_from_variant(res, p_context);
 							r_type.value = Variant();
 							r_type.type.is_constant = false;
 							found = true;
@@ -1920,7 +1934,7 @@ static bool _guess_expression_type(GDScriptParser::CompletionContext &p_context,
 					found = false;
 					break;
 				}
-				r_type = _type_from_variant(res);
+				r_type = _type_from_variant(res, p_context);
 				if (!v1_use_value || !v2_use_value) {
 					r_type.value = Variant();
 					r_type.type.is_constant = false;
@@ -2155,7 +2169,7 @@ static bool _guess_identifier_type(GDScriptParser::CompletionContext &p_context,
 		} else {
 			Ref<Script> scr = ResourceLoader::load(ScriptServer::get_global_class_path(p_identifier->name));
 			if (scr.is_valid()) {
-				r_type = _type_from_variant(scr);
+				r_type = _type_from_variant(scr, p_context);
 				r_type.type.is_meta_type = true;
 				return true;
 			}
@@ -2165,7 +2179,7 @@ static bool _guess_identifier_type(GDScriptParser::CompletionContext &p_context,
 
 	// Check global variables (including autoloads).
 	if (GDScriptLanguage::get_singleton()->get_named_globals_map().has(p_identifier->name)) {
-		r_type = _type_from_variant(GDScriptLanguage::get_singleton()->get_named_globals_map()[p_identifier->name]);
+		r_type = _type_from_variant(GDScriptLanguage::get_singleton()->get_named_globals_map()[p_identifier->name], p_context);
 		return true;
 	}
 
@@ -2218,7 +2232,7 @@ static bool _guess_identifier_type_from_base(GDScriptParser::CompletionContext &
 									const GDScriptParser::ExpressionNode *init = member.variable->initializer;
 									if (init->is_constant) {
 										r_type.value = init->reduced_value;
-										r_type = _type_from_variant(init->reduced_value);
+										r_type = _type_from_variant(init->reduced_value, p_context);
 										return true;
 									} else if (init->start_line == p_context.current_line) {
 										return false;
@@ -2245,7 +2259,7 @@ static bool _guess_identifier_type_from_base(GDScriptParser::CompletionContext &
 							r_type.enumeration = member.m_enum->identifier->name;
 							return true;
 						case GDScriptParser::ClassNode::Member::ENUM_VALUE:
-							r_type = _type_from_variant(member.enum_value.value);
+							r_type = _type_from_variant(member.enum_value.value, p_context);
 							return true;
 						case GDScriptParser::ClassNode::Member::SIGNAL:
 							r_type.type.type_source = GDScriptParser::DataType::ANNOTATED_EXPLICIT;
@@ -2281,7 +2295,7 @@ static bool _guess_identifier_type_from_base(GDScriptParser::CompletionContext &
 					HashMap<StringName, Variant> constants;
 					scr->get_constants(&constants);
 					if (constants.has(p_identifier)) {
-						r_type = _type_from_variant(constants[p_identifier]);
+						r_type = _type_from_variant(constants[p_identifier], p_context);
 						return true;
 					}
 
@@ -2345,7 +2359,7 @@ static bool _guess_identifier_type_from_base(GDScriptParser::CompletionContext &
 				bool valid = false;
 				Variant res = tmp.get(p_identifier, &valid);
 				if (valid) {
-					r_type = _type_from_variant(res);
+					r_type = _type_from_variant(res, p_context);
 					r_type.value = Variant();
 					r_type.type.is_constant = false;
 					return true;