Forráskód Böngészése

GDScript: Don't get invalid dictionary key during completion

We try to get the value out of a dictionary in order to establish its
type for completion purposes. However, if the dictionary or the key
is not a constant, we cannot safely get the actual value, so we skip
this and just try to infer from static typing.

Getting the value directly with `Variant::get()` generate errors if the
base is a Dictionary and the key is of an invalid type. So before trying
to get it we use the Dictionary validator to make sure it we can safely
try to get the key.
George Marques 2 hónapja
szülő
commit
81c7cae567

+ 17 - 7
modules/gdscript/gdscript_editor.cpp

@@ -44,6 +44,7 @@
 #include "core/core_constants.h"
 #include "core/io/file_access.h"
 #include "core/math/expression.h"
+#include "core/variant/container_type_validate.h"
 
 #ifdef TOOLS_ENABLED
 #include "core/config/project_settings.h"
@@ -2099,13 +2100,22 @@ static bool _guess_expression_type(GDScriptParser::CompletionContext &p_context,
 						break;
 					}
 
-					{
-						bool valid;
-						Variant value = base.value.get(index.value, &valid);
-						if (valid) {
-							r_type = _type_from_variant(value, p_context);
-							found = true;
-							break;
+					if (base.type.is_constant && index.type.is_constant) {
+						if (base.value.get_type() == Variant::DICTIONARY) {
+							Dictionary base_dict = base.value.operator Dictionary();
+							if (base_dict.get_key_validator().test_validate(index.value) && base_dict.has(index.value)) {
+								r_type = _type_from_variant(base_dict[index.value], p_context);
+								found = true;
+								break;
+							}
+						} else {
+							bool valid;
+							Variant value = base.value.get(index.value, &valid);
+							if (valid) {
+								r_type = _type_from_variant(value, p_context);
+								found = true;
+								break;
+							}
 						}
 					}
 

+ 1 - 1
modules/gdscript/tests/scripts/runtime/errors/typed_array_assign_wrong_to_typed.out

@@ -1,5 +1,5 @@
 GDTEST_RUNTIME_ERROR
->> ERROR: Condition "!other_script->inherits_script(script)" is true. Returning: false
+>> ERROR: Method/function failed. Returning: false
 >>   Attempted to assign an object into a TypedArray, that does not inherit from 'GDScript'.
 >> ERROR: Method/function failed.
 >>   Unable to convert array index 0 from "Object" to "Object".

+ 1 - 1
modules/gdscript/tests/scripts/runtime/errors/typed_dictionary_assign_wrong_to_typed.out

@@ -1,5 +1,5 @@
 GDTEST_RUNTIME_ERROR
->> ERROR: Condition "!other_script->inherits_script(script)" is true. Returning: false
+>> ERROR: Method/function failed. Returning: false
 >>   Attempted to assign an object into a TypedDictionary.Key, that does not inherit from 'GDScript'.
 >> ERROR: Method/function failed.
 >>   Unable to convert key from "Object" to "Object".