diff options
Diffstat (limited to 'modules/gdscript/gdscript.cpp')
-rw-r--r-- | modules/gdscript/gdscript.cpp | 152 |
1 files changed, 96 insertions, 56 deletions
diff --git a/modules/gdscript/gdscript.cpp b/modules/gdscript/gdscript.cpp index f29432666e..4385cf12ad 100644 --- a/modules/gdscript/gdscript.cpp +++ b/modules/gdscript/gdscript.cpp @@ -152,12 +152,13 @@ Variant GDScript::_new(const Variant **p_args, int p_argcount, Variant::CallErro } ERR_FAIL_COND_V(_baseptr->native.is_null(), Variant()); - if (_baseptr->native.ptr()) { owner = _baseptr->native->instance(); } else { owner = memnew(Reference); //by default, no base means use reference } + ERR_EXPLAIN("Can't inherit from a virtual class"); + ERR_FAIL_COND_V(!owner, Variant()); Reference *r = Object::cast_to<Reference>(owner); if (r) { @@ -1108,12 +1109,12 @@ void GDScriptInstance::get_property_list(List<PropertyInfo> *p_properties) const //instance a fake script for editing the values Vector<_GDScriptMemberSort> msort; - for (Map<StringName, PropertyInfo>::Element *E = sptr->member_info.front(); E; E = E->next()) { + for (Map<StringName, PropertyInfo>::Element *F = sptr->member_info.front(); F; F = F->next()) { _GDScriptMemberSort ms; - ERR_CONTINUE(!sptr->member_indices.has(E->key())); - ms.index = sptr->member_indices[E->key()].index; - ms.name = E->key(); + ERR_CONTINUE(!sptr->member_indices.has(F->key())); + ms.index = sptr->member_indices[F->key()].index; + ms.name = F->key(); msort.push_back(ms); } @@ -1834,73 +1835,92 @@ String GDScriptLanguage::get_global_class_name(const String &p_path, String *r_b PoolVector<uint8_t> sourcef; Error err; - FileAccess *f = FileAccess::open(p_path, FileAccess::READ, &err); + FileAccessRef f = FileAccess::open(p_path, FileAccess::READ, &err); if (err) { return String(); } - int len = f->get_len(); - sourcef.resize(len + 1); - PoolVector<uint8_t>::Write w = sourcef.write(); - int r = f->get_buffer(w.ptr(), len); - f->close(); - memdelete(f); - ERR_FAIL_COND_V(r != len, String()); - w[len] = 0; - - String s; - if (s.parse_utf8((const char *)w.ptr())) { - return String(); - } + String source = f->get_as_utf8_string(); GDScriptParser parser; - - parser.parse(s, p_path.get_base_dir(), true, p_path); + parser.parse(source, p_path.get_base_dir(), true, p_path, false, NULL, true); if (parser.get_parse_tree() && parser.get_parse_tree()->type == GDScriptParser::Node::TYPE_CLASS) { const GDScriptParser::ClassNode *c = static_cast<const GDScriptParser::ClassNode *>(parser.get_parse_tree()); + if (r_icon_path) { + if (c->icon_path.empty() || c->icon_path.is_abs_path()) + *r_icon_path = c->icon_path; + else if (c->icon_path.is_rel_path()) + *r_icon_path = p_path.get_base_dir().plus_file(c->icon_path).simplify_path(); + } if (r_base_type) { - GDScriptParser::DataType base_type; - if (c->base_type.has_type) { - base_type = c->base_type; - while (base_type.has_type && base_type.kind != GDScriptParser::DataType::NATIVE) { - switch (base_type.kind) { - case GDScriptParser::DataType::CLASS: { - base_type = base_type.class_type->base_type; - } break; - case GDScriptParser::DataType::GDSCRIPT: { - Ref<GDScript> gds = base_type.script_type; - if (gds.is_valid()) { - base_type.kind = GDScriptParser::DataType::NATIVE; - base_type.native_type = gds->get_instance_base_type(); - } else { - base_type = GDScriptParser::DataType(); + + const GDScriptParser::ClassNode *subclass = c; + String path = p_path; + GDScriptParser subparser; + while (subclass) { + if (subclass->extends_used) { + if (subclass->extends_file) { + if (subclass->extends_class.size() == 0) { + get_global_class_name(subclass->extends_file, r_base_type); + subclass = NULL; + break; + } else { + Vector<StringName> extend_classes = subclass->extends_class; + + FileAccessRef subfile = FileAccess::open(subclass->extends_file, FileAccess::READ); + if (!subfile) { + break; + } + String subsource = subfile->get_as_utf8_string(); + + if (subsource.empty()) { + break; } - } break; - default: { - base_type = GDScriptParser::DataType(); - } break; + String subpath = subclass->extends_file; + if (subpath.is_rel_path()) { + subpath = path.get_base_dir().plus_file(subpath).simplify_path(); + } + + if (OK != subparser.parse(subsource, subpath.get_base_dir(), true, subpath, false, NULL, true)) { + break; + } + path = subpath; + if (!subparser.get_parse_tree() || subparser.get_parse_tree()->type != GDScriptParser::Node::TYPE_CLASS) { + break; + } + subclass = static_cast<const GDScriptParser::ClassNode *>(subparser.get_parse_tree()); + + while (extend_classes.size() > 0) { + bool found = false; + for (int i = 0; i < subclass->subclasses.size(); i++) { + const GDScriptParser::ClassNode *inner_class = subclass->subclasses[i]; + if (inner_class->name == extend_classes[0]) { + extend_classes.remove(0); + found = true; + subclass = inner_class; + break; + } + } + if (!found) { + subclass = NULL; + break; + } + } + } + } else if (subclass->extends_class.size() == 1) { + *r_base_type = subclass->extends_class[0]; + subclass = NULL; + } else { + break; } - } - } - if (base_type.has_type) { - *r_base_type = base_type.native_type; - } else { - // Fallback - if (c->extends_used && c->extends_class.size() == 1) { - *r_base_type = c->extends_class[0]; - } else if (!c->extends_used) { + } else { *r_base_type = "Reference"; + subclass = NULL; } } } - if (r_icon_path) { - if (c->icon_path.empty() || c->icon_path.is_abs_path()) - *r_icon_path = c->icon_path; - else if (c->icon_path.is_rel_path()) - *r_icon_path = p_path.get_base_dir().plus_file(c->icon_path).simplify_path(); - } return c->name; } @@ -1945,7 +1965,7 @@ String GDScriptWarning::get_message() const { return "Assignment operation, but the function '" + symbols[0] + "()' returns void."; } break; case NARROWING_CONVERSION: { - return "Narrowing coversion (float is converted to int and lose precision)."; + return "Narrowing conversion (float is converted to int and loses precision)."; } break; case FUNCTION_MAY_YIELD: { CHECK_SYMBOLS(1); @@ -2182,6 +2202,26 @@ String ResourceFormatLoaderGDScript::get_resource_type(const String &p_path) con return ""; } +void ResourceFormatLoaderGDScript::get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types) { + + FileAccessRef file = FileAccess::open(p_path, FileAccess::READ); + ERR_FAIL_COND(!file); + + String source = file->get_as_utf8_string(); + if (source.empty()) { + return; + } + + GDScriptParser parser; + if (OK != parser.parse(source, p_path.get_base_dir(), true, p_path, false, NULL, true)) { + return; + } + + for (const List<String>::Element *E = parser.get_dependencies().front(); E; E = E->next()) { + p_dependencies->push_back(E->get()); + } +} + Error ResourceFormatSaverGDScript::save(const String &p_path, const RES &p_resource, uint32_t p_flags) { Ref<GDScript> sqscr = p_resource; |