Merge pull request #68430 from anvilfolk/check-superclass-member
Fix minor inheritance errors
This commit is contained in:
commit
6b6572963f
6 changed files with 32 additions and 5 deletions
|
@ -32,6 +32,7 @@
|
||||||
|
|
||||||
#include "core/config/engine.h"
|
#include "core/config/engine.h"
|
||||||
#include "core/config/project_settings.h"
|
#include "core/config/project_settings.h"
|
||||||
|
#include "core/core_string_names.h"
|
||||||
#include "core/io/file_access.h"
|
#include "core/io/file_access.h"
|
||||||
#include "core/io/resource_loader.h"
|
#include "core/io/resource_loader.h"
|
||||||
#include "core/object/class_db.h"
|
#include "core/object/class_db.h"
|
||||||
|
@ -132,7 +133,7 @@ static GDScriptParser::DataType make_builtin_meta_type(Variant::Type p_type) {
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GDScriptAnalyzer::has_member_name_conflict_in_script_class(const StringName &p_member_name, const GDScriptParser::ClassNode *p_class) {
|
bool GDScriptAnalyzer::has_member_name_conflict_in_script_class(const StringName &p_member_name, const GDScriptParser::ClassNode *p_class, const GDScriptParser::Node *p_member) {
|
||||||
if (p_class->members_indices.has(p_member_name)) {
|
if (p_class->members_indices.has(p_member_name)) {
|
||||||
int index = p_class->members_indices[p_member_name];
|
int index = p_class->members_indices[p_member_name];
|
||||||
const GDScriptParser::ClassNode::Member *member = &p_class->members[index];
|
const GDScriptParser::ClassNode::Member *member = &p_class->members[index];
|
||||||
|
@ -145,6 +146,9 @@ bool GDScriptAnalyzer::has_member_name_conflict_in_script_class(const StringName
|
||||||
member->type == GDScriptParser::ClassNode::Member::SIGNAL) {
|
member->type == GDScriptParser::ClassNode::Member::SIGNAL) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
if (p_member->type != GDScriptParser::Node::FUNCTION && member->type == GDScriptParser::ClassNode::Member::FUNCTION) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@ -160,6 +164,9 @@ bool GDScriptAnalyzer::has_member_name_conflict_in_native_type(const StringName
|
||||||
if (ClassDB::has_integer_constant(p_native_type_string, p_member_name)) {
|
if (ClassDB::has_integer_constant(p_native_type_string, p_member_name)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
if (p_member_name == CoreStringNames::get_singleton()->_script) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -187,14 +194,15 @@ Error GDScriptAnalyzer::check_class_member_name_conflict(const GDScriptParser::C
|
||||||
const GDScriptParser::DataType *current_data_type = &p_class_node->base_type;
|
const GDScriptParser::DataType *current_data_type = &p_class_node->base_type;
|
||||||
while (current_data_type && current_data_type->kind == GDScriptParser::DataType::Kind::CLASS) {
|
while (current_data_type && current_data_type->kind == GDScriptParser::DataType::Kind::CLASS) {
|
||||||
GDScriptParser::ClassNode *current_class_node = current_data_type->class_type;
|
GDScriptParser::ClassNode *current_class_node = current_data_type->class_type;
|
||||||
if (has_member_name_conflict_in_script_class(p_member_name, current_class_node)) {
|
if (has_member_name_conflict_in_script_class(p_member_name, current_class_node, p_member_node)) {
|
||||||
push_error(vformat(R"(The member "%s" already exists in a parent class.)", p_member_name),
|
push_error(vformat(R"(The member "%s" already exists in parent class %s.)", p_member_name, current_class_node->identifier->name),
|
||||||
p_member_node);
|
p_member_node);
|
||||||
return ERR_PARSE_ERROR;
|
return ERR_PARSE_ERROR;
|
||||||
}
|
}
|
||||||
current_data_type = ¤t_class_node->base_type;
|
current_data_type = ¤t_class_node->base_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// No need for native class recursion because Node exposes all Object's properties.
|
||||||
if (current_data_type && current_data_type->kind == GDScriptParser::DataType::Kind::NATIVE) {
|
if (current_data_type && current_data_type->kind == GDScriptParser::DataType::Kind::NATIVE) {
|
||||||
if (current_data_type->native_type != StringName()) {
|
if (current_data_type->native_type != StringName()) {
|
||||||
return check_native_member_name_conflict(
|
return check_native_member_name_conflict(
|
||||||
|
@ -2912,7 +2920,7 @@ void GDScriptAnalyzer::reduce_identifier_from_base(GDScriptParser::IdentifierNod
|
||||||
base_class = base_class->base_type.class_type;
|
base_class = base_class->base_type.class_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check native members.
|
// Check native members. No need for native class recursion because Node exposes all Object's properties.
|
||||||
const StringName &native = base.native_type;
|
const StringName &native = base.native_type;
|
||||||
|
|
||||||
if (class_exists(native)) {
|
if (class_exists(native)) {
|
||||||
|
|
|
@ -45,7 +45,7 @@ class GDScriptAnalyzer {
|
||||||
List<GDScriptParser::LambdaNode *> lambda_stack;
|
List<GDScriptParser::LambdaNode *> lambda_stack;
|
||||||
|
|
||||||
// Tests for detecting invalid overloading of script members
|
// Tests for detecting invalid overloading of script members
|
||||||
static _FORCE_INLINE_ bool has_member_name_conflict_in_script_class(const StringName &p_name, const GDScriptParser::ClassNode *p_current_class_node);
|
static _FORCE_INLINE_ bool has_member_name_conflict_in_script_class(const StringName &p_name, const GDScriptParser::ClassNode *p_current_class_node, const GDScriptParser::Node *p_member);
|
||||||
static _FORCE_INLINE_ bool has_member_name_conflict_in_native_type(const StringName &p_name, const StringName &p_native_type_string);
|
static _FORCE_INLINE_ bool has_member_name_conflict_in_native_type(const StringName &p_name, const StringName &p_native_type_string);
|
||||||
Error check_native_member_name_conflict(const StringName &p_member_name, const GDScriptParser::Node *p_member_node, const StringName &p_native_type_string);
|
Error check_native_member_name_conflict(const StringName &p_member_name, const GDScriptParser::Node *p_member_node, const StringName &p_native_type_string);
|
||||||
Error check_class_member_name_conflict(const GDScriptParser::ClassNode *p_class_node, const StringName &p_member_name, const GDScriptParser::Node *p_member_node);
|
Error check_class_member_name_conflict(const GDScriptParser::ClassNode *p_class_node, const StringName &p_member_name, const GDScriptParser::Node *p_member_node);
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
extends Node
|
||||||
|
|
||||||
|
var script: int
|
||||||
|
|
||||||
|
func test():
|
||||||
|
pass
|
|
@ -0,0 +1,2 @@
|
||||||
|
GDTEST_ANALYZER_ERROR
|
||||||
|
Member "script" redefined (original in native class 'Node')
|
|
@ -0,0 +1,9 @@
|
||||||
|
func test():
|
||||||
|
pass
|
||||||
|
|
||||||
|
class A:
|
||||||
|
func overload_me():
|
||||||
|
pass
|
||||||
|
|
||||||
|
class B extends A:
|
||||||
|
var overload_me
|
|
@ -0,0 +1,2 @@
|
||||||
|
GDTEST_ANALYZER_ERROR
|
||||||
|
The member "overload_me" already exists in parent class A.
|
Loading…
Reference in a new issue