diff --git a/modules/gdscript/gdscript_analyzer.cpp b/modules/gdscript/gdscript_analyzer.cpp index a2cab25ce8ab..34535887afe7 100644 --- a/modules/gdscript/gdscript_analyzer.cpp +++ b/modules/gdscript/gdscript_analyzer.cpp @@ -479,7 +479,24 @@ Error GDScriptAnalyzer::resolve_class_inheritance(GDScriptParser::ClassNode *p_c } if (look_class->has_member(name)) { resolve_class_member(look_class, name, id); - base = look_class->get_member(name).get_datatype(); + GDScriptParser::ClassNode::Member member = look_class->get_member(name); + GDScriptParser::DataType member_datatype = member.get_datatype(); + + switch (member.type) { + case GDScriptParser::ClassNode::Member::CLASS: + break; // OK. + case GDScriptParser::ClassNode::Member::CONSTANT: + if (member_datatype.kind != GDScriptParser::DataType::SCRIPT && member_datatype.kind != GDScriptParser::DataType::CLASS) { + push_error(vformat(R"(Constant "%s" is not a preloaded script or class.)", name), id); + return ERR_PARSE_ERROR; + } + break; + default: + push_error(vformat(R"(Cannot use %s "%s" in extends chain.)", member.get_type_name(), name), id); + return ERR_PARSE_ERROR; + } + + base = member_datatype; found = true; break; } @@ -506,6 +523,9 @@ Error GDScriptAnalyzer::resolve_class_inheritance(GDScriptParser::ClassNode *p_c if (!id_type.is_set()) { push_error(vformat(R"(Could not find nested type "%s".)", id->name), id); return ERR_PARSE_ERROR; + } else if (id_type.kind != GDScriptParser::DataType::SCRIPT && id_type.kind != GDScriptParser::DataType::CLASS) { + push_error(vformat(R"(Identifier "%s" is not a preloaded script or class.)", id->name), id); + return ERR_PARSE_ERROR; } base = id_type; diff --git a/modules/gdscript/tests/scripts/analyzer/errors/extend_non_class_constant_1.gd b/modules/gdscript/tests/scripts/analyzer/errors/extend_non_class_constant_1.gd new file mode 100644 index 000000000000..72af0991587c --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/errors/extend_non_class_constant_1.gd @@ -0,0 +1,9 @@ +# GH-75870 + +const A = 1 + +class B extends A: + pass + +func test(): + pass diff --git a/modules/gdscript/tests/scripts/analyzer/errors/extend_non_class_constant_1.out b/modules/gdscript/tests/scripts/analyzer/errors/extend_non_class_constant_1.out new file mode 100644 index 000000000000..65d629a35b69 --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/errors/extend_non_class_constant_1.out @@ -0,0 +1,2 @@ +GDTEST_ANALYZER_ERROR +Constant "A" is not a preloaded script or class. diff --git a/modules/gdscript/tests/scripts/analyzer/errors/extend_non_class_constant_2.gd b/modules/gdscript/tests/scripts/analyzer/errors/extend_non_class_constant_2.gd new file mode 100644 index 000000000000..fe334f8cb77d --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/errors/extend_non_class_constant_2.gd @@ -0,0 +1,12 @@ +# GH-75870 + +class A: + const X = 1 + +const Y = A.X # A.X is now resolved. + +class B extends A.X: + pass + +func test(): + pass diff --git a/modules/gdscript/tests/scripts/analyzer/errors/extend_non_class_constant_2.out b/modules/gdscript/tests/scripts/analyzer/errors/extend_non_class_constant_2.out new file mode 100644 index 000000000000..951cfb1ea413 --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/errors/extend_non_class_constant_2.out @@ -0,0 +1,2 @@ +GDTEST_ANALYZER_ERROR +Identifier "X" is not a preloaded script or class. diff --git a/modules/gdscript/tests/scripts/analyzer/errors/extend_variable.gd b/modules/gdscript/tests/scripts/analyzer/errors/extend_variable.gd new file mode 100644 index 000000000000..6574d4cf31c0 --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/errors/extend_variable.gd @@ -0,0 +1,9 @@ +# GH-75870 + +var A = 1 + +class B extends A: + pass + +func test(): + pass diff --git a/modules/gdscript/tests/scripts/analyzer/errors/extend_variable.out b/modules/gdscript/tests/scripts/analyzer/errors/extend_variable.out new file mode 100644 index 000000000000..7b39af69792f --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/errors/extend_variable.out @@ -0,0 +1,2 @@ +GDTEST_ANALYZER_ERROR +Cannot use variable "A" in extends chain.