Browse Source

Merge pull request #52100 from vnen/gdscript-access-outer-constants

GDScript: Allow access to outer constant and enum values
Rémi Verschelde 3 years ago
parent
commit
0c2ab55a58

+ 25 - 9
modules/gdscript/gdscript_analyzer.cpp

@@ -681,8 +681,9 @@ void GDScriptAnalyzer::resolve_class_interface(GDScriptParser::ClassNode *p_clas
 					specified_type.is_meta_type = false;
 				}
 
-				GDScriptParser::DataType datatype = member.constant->get_datatype();
+				GDScriptParser::DataType datatype;
 				if (member.constant->initializer) {
+					datatype = member.constant->initializer->get_datatype();
 					if (member.constant->initializer->type == GDScriptParser::Node::ARRAY) {
 						GDScriptParser::ArrayNode *array = static_cast<GDScriptParser::ArrayNode *>(member.constant->initializer);
 						const_fold_array(array);
@@ -2516,14 +2517,29 @@ void GDScriptAnalyzer::reduce_identifier_from_base(GDScriptParser::IdentifierNod
 		while (outer != nullptr) {
 			if (outer->has_member(name)) {
 				const GDScriptParser::ClassNode::Member &member = outer->get_member(name);
-				if (member.type == GDScriptParser::ClassNode::Member::CONSTANT) {
-					// TODO: Make sure loops won't cause problem. And make special error message for those.
-					// For out-of-order resolution:
-					reduce_expression(member.constant->initializer);
-					p_identifier->set_datatype(member.get_datatype());
-					p_identifier->is_constant = true;
-					p_identifier->reduced_value = member.constant->initializer->reduced_value;
-					return;
+				switch (member.type) {
+					case GDScriptParser::ClassNode::Member::CONSTANT: {
+						// TODO: Make sure loops won't cause problem. And make special error message for those.
+						// For out-of-order resolution:
+						reduce_expression(member.constant->initializer);
+						p_identifier->set_datatype(member.get_datatype());
+						p_identifier->is_constant = true;
+						p_identifier->reduced_value = member.constant->initializer->reduced_value;
+						return;
+					} break;
+					case GDScriptParser::ClassNode::Member::ENUM_VALUE: {
+						p_identifier->set_datatype(member.get_datatype());
+						p_identifier->is_constant = true;
+						p_identifier->reduced_value = member.enum_value.value;
+						return;
+					} break;
+					case GDScriptParser::ClassNode::Member::ENUM: {
+						p_identifier->set_datatype(member.get_datatype());
+						p_identifier->is_constant = false;
+						return;
+					} break;
+					default:
+						break;
 				}
 			}
 			outer = outer->outer;

+ 16 - 0
modules/gdscript/tests/scripts/analyzer/features/constants_from_parent.gd

@@ -0,0 +1,16 @@
+extends Node
+
+const NO_TYPE_CONST = 0
+const TYPE_CONST: int = 1
+const GUESS_TYPE_CONST := 2
+
+class Test:
+	var a = NO_TYPE_CONST
+	var b = TYPE_CONST
+	var c = GUESS_TYPE_CONST
+
+func test():
+	var test_instance = Test.new()
+	prints("a", test_instance.a, test_instance.a == NO_TYPE_CONST)
+	prints("b", test_instance.b, test_instance.b == TYPE_CONST)
+	prints("c", test_instance.c, test_instance.c == GUESS_TYPE_CONST)

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

@@ -0,0 +1,4 @@
+GDTEST_OK
+a 0 True
+b 1 True
+c 2 True

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

@@ -0,0 +1,14 @@
+extends Node
+
+enum Named { VALUE_A, VALUE_B, VALUE_C = 42 }
+
+class Test:
+	var a = Named.VALUE_A
+	var b = Named.VALUE_B
+	var c = Named.VALUE_C
+
+func test():
+	var test_instance = Test.new()
+	prints("a", test_instance.a, test_instance.a == Named.VALUE_A)
+	prints("b", test_instance.b, test_instance.b == Named.VALUE_B)
+	prints("c", test_instance.c, test_instance.c == Named.VALUE_C)

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

@@ -0,0 +1,4 @@
+GDTEST_OK
+a 0 True
+b 1 True
+c 42 True

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

@@ -0,0 +1,14 @@
+extends Node
+
+enum { VALUE_A, VALUE_B, VALUE_C = 42 }
+
+class Test:
+	var a = VALUE_A
+	var b = VALUE_B
+	var c = VALUE_C
+
+func test():
+	var test_instance = Test.new()
+	prints("a", test_instance.a, test_instance.a == VALUE_A)
+	prints("b", test_instance.b, test_instance.b == VALUE_B)
+	prints("c", test_instance.c, test_instance.c == VALUE_C)

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

@@ -0,0 +1,4 @@
+GDTEST_OK
+a 0 True
+b 1 True
+c 42 True