GDScript: Fix: update member cache of subclasses
Currently, the member cache for subclasses (sometimes called inner classes in the codebase) is not updated. This causes users being unable to see exported properties inherited from an inner class in the editor.
This commit is contained in:
parent
e343dbbcc1
commit
9ca9fb3c2f
@ -451,11 +451,18 @@ void GDScript::set_source_code(const String &p_code) {
|
||||
}
|
||||
source = p_code;
|
||||
#ifdef TOOLS_ENABLED
|
||||
source_changed_cache = true;
|
||||
mark_source_changed();
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef TOOLS_ENABLED
|
||||
void GDScript::mark_source_changed() {
|
||||
_source_changed_cache = true;
|
||||
for (KeyValue<StringName, Ref<GDScript>> &inner : subclasses) {
|
||||
inner.value->mark_source_changed();
|
||||
}
|
||||
}
|
||||
|
||||
void GDScript::_update_exports_values(HashMap<StringName, Variant> &values, List<PropertyInfo> &propnames) {
|
||||
for (const KeyValue<StringName, Variant> &E : member_default_values_cache) {
|
||||
values[E.key] = E.value;
|
||||
@ -505,8 +512,9 @@ bool GDScript::_update_exports(bool *r_err, bool p_recursive_call, PlaceHolderSc
|
||||
|
||||
bool changed = p_base_exports_changed;
|
||||
|
||||
if (source_changed_cache) {
|
||||
source_changed_cache = false;
|
||||
if (_source_changed_cache) {
|
||||
// Only set to false for this instance: subclasses have to update themselves
|
||||
_source_changed_cache = false;
|
||||
changed = true;
|
||||
|
||||
String basedir = path;
|
||||
@ -521,17 +529,27 @@ bool GDScript::_update_exports(bool *r_err, bool p_recursive_call, PlaceHolderSc
|
||||
|
||||
GDScriptParser parser;
|
||||
GDScriptAnalyzer analyzer(&parser);
|
||||
Error err = parser.parse(source, path, false);
|
||||
|
||||
const String *s = &source;
|
||||
if (!is_root_script()) {
|
||||
// Subclasses are contained in their root script's source
|
||||
s = &get_root_script()->source;
|
||||
}
|
||||
Error err = parser.parse(*s, path, false);
|
||||
|
||||
if (err == OK && analyzer.analyze() == OK) {
|
||||
const GDScriptParser::ClassNode *c = parser.get_tree();
|
||||
if (!is_root_script()) {
|
||||
// get_tree() would return outer class. We are in that tree somewhere!
|
||||
c = c->find_class(fully_qualified_name);
|
||||
}
|
||||
|
||||
if (base_cache.is_valid()) {
|
||||
base_cache->inheriters_cache.erase(get_instance_id());
|
||||
base_cache = Ref<GDScript>();
|
||||
}
|
||||
|
||||
GDScriptParser::DataType base_type = parser.get_tree()->base_type;
|
||||
GDScriptParser::DataType base_type = c->base_type;
|
||||
if (base_type.kind == GDScriptParser::DataType::CLASS) {
|
||||
Ref<GDScript> bf = GDScriptCache::get_full_script(base_type.script_path, err, path);
|
||||
if (err == OK) {
|
||||
@ -1110,7 +1128,7 @@ Error GDScript::load_source_code(const String &p_path) {
|
||||
path = p_path;
|
||||
path_valid = true;
|
||||
#ifdef TOOLS_ENABLED
|
||||
source_changed_cache = true;
|
||||
mark_source_changed();
|
||||
set_edited(false);
|
||||
set_last_modified_time(FileAccess::get_modified_time(path));
|
||||
#endif // TOOLS_ENABLED
|
||||
|
@ -153,7 +153,8 @@ private:
|
||||
HashMap<StringName, Variant> member_default_values_cache;
|
||||
Ref<GDScript> base_cache;
|
||||
HashSet<ObjectID> inheriters_cache;
|
||||
bool source_changed_cache = false;
|
||||
bool _source_changed_cache = false;
|
||||
void mark_source_changed();
|
||||
bool placeholder_fallback_enabled = false;
|
||||
void _update_exports_values(HashMap<StringName, Variant> &values, List<PropertyInfo> &propnames);
|
||||
|
||||
|
@ -3086,6 +3086,11 @@ void GDScriptCompiler::make_scripts(GDScript *p_script, const GDScriptParser::Cl
|
||||
|
||||
make_scripts(subclass.ptr(), inner_class, p_keep_state);
|
||||
}
|
||||
|
||||
#ifdef TOOLS_ENABLED
|
||||
// Mark all newly created subclasses as having changed source
|
||||
p_script->mark_source_changed();
|
||||
#endif // TOOLS_ENABLED
|
||||
}
|
||||
|
||||
GDScriptCompiler::FunctionLambdaInfo GDScriptCompiler::_get_function_replacement_info(GDScriptFunction *p_func, int p_index, int p_depth, GDScriptFunction *p_parent_func) {
|
||||
|
@ -757,6 +757,23 @@ public:
|
||||
ERR_FAIL_INDEX(members_indices[p_name], members.size());
|
||||
members.write[members_indices[p_name]].enum_value.doc_data = p_doc_data;
|
||||
}
|
||||
|
||||
const ClassNode *find_class(const String &p_fqcn) const {
|
||||
if (fqcn == p_fqcn) {
|
||||
return this;
|
||||
}
|
||||
|
||||
for (const Member &member : members) {
|
||||
if (member.type == Member::CLASS) {
|
||||
const ClassNode *c = member.m_class->find_class(p_fqcn);
|
||||
if (c != nullptr) {
|
||||
return c;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
#endif // TOOLS_ENABLED
|
||||
|
||||
bool resolved_interface = false;
|
||||
|
Loading…
Reference in New Issue
Block a user