summaryrefslogtreecommitdiff
path: root/modules/gdscript/gdscript.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'modules/gdscript/gdscript.cpp')
-rw-r--r--modules/gdscript/gdscript.cpp152
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;