Просмотр исходного кода

Merge pull request #53478 from vnen/gdscript-avoid-hard-inference

Rémi Verschelde 4 лет назад
Родитель
Сommit
ba0a103e29

+ 8 - 11
modules/gdscript/gdscript_analyzer.cpp

@@ -1742,7 +1742,7 @@ void GDScriptAnalyzer::reduce_assignment(GDScriptParser::AssignmentNode *p_assig
 		push_error("Cannot assign a new value to a constant.", p_assignment->assignee);
 	}
 
-	if (!assignee_type.is_variant() && !assigned_value_type.is_variant()) {
+	if (!assignee_type.is_variant() && assigned_value_type.is_hard_type()) {
 		bool compatible = true;
 		GDScriptParser::DataType op_type = assigned_value_type;
 		if (p_assignment->operation != GDScriptParser::AssignmentNode::OP_NONE) {
@@ -1794,27 +1794,24 @@ void GDScriptAnalyzer::reduce_assignment(GDScriptParser::AssignmentNode *p_assig
 			case GDScriptParser::IdentifierNode::FUNCTION_PARAMETER: {
 				GDScriptParser::DataType id_type = identifier->parameter_source->get_datatype();
 				if (!id_type.is_hard_type()) {
-					id_type = assigned_value_type;
-					id_type.type_source = GDScriptParser::DataType::INFERRED;
-					id_type.is_constant = false;
+					id_type.kind = GDScriptParser::DataType::VARIANT;
+					id_type.type_source = GDScriptParser::DataType::UNDETECTED;
 					identifier->parameter_source->set_datatype(id_type);
 				}
 			} break;
 			case GDScriptParser::IdentifierNode::LOCAL_VARIABLE: {
 				GDScriptParser::DataType id_type = identifier->variable_source->get_datatype();
 				if (!id_type.is_hard_type()) {
-					id_type = assigned_value_type;
-					id_type.type_source = GDScriptParser::DataType::INFERRED;
-					id_type.is_constant = false;
+					id_type.kind = GDScriptParser::DataType::VARIANT;
+					id_type.type_source = GDScriptParser::DataType::UNDETECTED;
 					identifier->variable_source->set_datatype(id_type);
 				}
 			} break;
 			case GDScriptParser::IdentifierNode::LOCAL_ITERATOR: {
 				GDScriptParser::DataType id_type = identifier->bind_source->get_datatype();
 				if (!id_type.is_hard_type()) {
-					id_type = assigned_value_type;
-					id_type.type_source = GDScriptParser::DataType::INFERRED;
-					id_type.is_constant = false;
+					id_type.kind = GDScriptParser::DataType::VARIANT;
+					id_type.type_source = GDScriptParser::DataType::UNDETECTED;
 					identifier->variable_source->set_datatype(id_type);
 				}
 			} break;
@@ -2941,7 +2938,7 @@ void GDScriptAnalyzer::reduce_subscript(GDScriptParser::SubscriptNode *p_subscri
 		} else {
 			GDScriptParser::DataType base_type = p_subscript->base->get_datatype();
 
-			if (base_type.is_variant()) {
+			if (base_type.is_variant() || !base_type.is_hard_type()) {
 				result_type.kind = GDScriptParser::DataType::VARIANT;
 				mark_node_unsafe(p_subscript);
 			} else {

+ 6 - 7
modules/gdscript/tests/gdscript_test_runner.cpp

@@ -133,13 +133,12 @@ GDScriptTestRunner::GDScriptTestRunner(const String &p_source_dir, bool p_init_l
 
 	if (do_init_languages) {
 		init_language(p_source_dir);
-
-		// Enable all warnings for GDScript, so we can test them.
-		ProjectSettings::get_singleton()->set_setting("debug/gdscript/warnings/enable", true);
-		for (int i = 0; i < (int)GDScriptWarning::WARNING_MAX; i++) {
-			String warning = GDScriptWarning::get_name_from_code((GDScriptWarning::Code)i).to_lower();
-			ProjectSettings::get_singleton()->set_setting("debug/gdscript/warnings/" + warning, true);
-		}
+	}
+	// Enable all warnings for GDScript, so we can test them.
+	ProjectSettings::get_singleton()->set_setting("debug/gdscript/warnings/enable", true);
+	for (int i = 0; i < (int)GDScriptWarning::WARNING_MAX; i++) {
+		String warning = GDScriptWarning::get_name_from_code((GDScriptWarning::Code)i).to_lower();
+		ProjectSettings::get_singleton()->set_setting("debug/gdscript/warnings/" + warning, true);
 	}
 
 	// Enable printing to show results

+ 4 - 0
modules/gdscript/tests/scripts/analyzer/features/auto_inferred_type_dont_error.out

@@ -1,2 +1,6 @@
 GDTEST_OK
+>> WARNING
+>> Line: 6
+>> UNSAFE_METHOD_ACCESS
+>> The method 'free' is not present on the inferred type 'Variant' (but may be present on a subtype).
 Ok

+ 11 - 0
modules/gdscript/tests/scripts/analyzer/features/class_inference_is_weak.gd

@@ -0,0 +1,11 @@
+# https://github.com/godotengine/godot/issues/43503
+
+var test_var = null
+
+
+func test():
+	print(test_var.x)
+
+
+func _init():
+	test_var = Vector3()

+ 2 - 0
modules/gdscript/tests/scripts/analyzer/features/class_inference_is_weak.out

@@ -0,0 +1,2 @@
+GDTEST_OK
+0

+ 14 - 0
modules/gdscript/tests/scripts/analyzer/features/local_inference_is_weak.gd

@@ -0,0 +1,14 @@
+# https://github.com/godotengine/godot/issues/41064
+var x = true
+
+func test():
+	var int_var: int = 0
+	var dyn_var = 2
+
+	if x:
+		dyn_var = 5
+	else:
+		dyn_var = Node.new()
+
+	int_var = dyn_var
+	print(int_var)

+ 2 - 0
modules/gdscript/tests/scripts/analyzer/features/local_inference_is_weak.out

@@ -0,0 +1,2 @@
+GDTEST_OK
+5