summaryrefslogtreecommitdiff
path: root/modules/gdscript
diff options
context:
space:
mode:
Diffstat (limited to 'modules/gdscript')
-rw-r--r--modules/gdscript/gdscript.cpp46
-rw-r--r--modules/gdscript/gdscript.h2
-rw-r--r--modules/gdscript/gdscript_compiler.cpp22
-rw-r--r--modules/gdscript/gdscript_compiler.h10
-rw-r--r--modules/gdscript/gdscript_function.cpp33
-rw-r--r--modules/gdscript/gdscript_function.h4
-rw-r--r--modules/gdscript/gdscript_parser.cpp27
7 files changed, 70 insertions, 74 deletions
diff --git a/modules/gdscript/gdscript.cpp b/modules/gdscript/gdscript.cpp
index 159085df34..538249c8e2 100644
--- a/modules/gdscript/gdscript.cpp
+++ b/modules/gdscript/gdscript.cpp
@@ -421,31 +421,40 @@ bool GDScript::_update_exports() {
base_cache = Ref<GDScript>();
}
- if (c->extends_used && String(c->extends_file) != "" && String(c->extends_file) != get_path()) {
-
- String path = c->extends_file;
- if (path.is_rel_path()) {
-
- String base = get_path();
- if (base == "" || base.is_rel_path()) {
-
- ERR_PRINT(("Could not resolve relative path for parent class: " + path).utf8().get_data());
- } else {
- path = base.get_base_dir().plus_file(path);
+ if (c->extends_used) {
+ String path = "";
+ if (String(c->extends_file) != "" && String(c->extends_file) != get_path()) {
+ path = c->extends_file;
+ if (path.is_rel_path()) {
+
+ String base = get_path();
+ if (base == "" || base.is_rel_path()) {
+
+ ERR_PRINT(("Could not resolve relative path for parent class: " + path).utf8().get_data());
+ } else {
+ path = base.get_base_dir().plus_file(path);
+ }
}
+ } else if (c->extends_class.size() != 0) {
+ String base = c->extends_class[0];
+
+ if (ScriptServer::is_global_class(base))
+ path = ScriptServer::get_global_class_path(base);
}
- if (path != get_path()) {
+ if (path != "") {
+ if (path != get_path()) {
- Ref<GDScript> bf = ResourceLoader::load(path);
+ Ref<GDScript> bf = ResourceLoader::load(path);
- if (bf.is_valid()) {
+ if (bf.is_valid()) {
- base_cache = bf;
- bf->inheriters_cache.insert(get_instance_id());
+ base_cache = bf;
+ bf->inheriters_cache.insert(get_instance_id());
+ }
+ } else {
+ ERR_PRINT(("Path extending itself in " + path).utf8().get_data());
}
- } else {
- ERR_PRINT(("Path extending itself in " + path).utf8().get_data());
}
}
@@ -858,7 +867,6 @@ bool GDScript::has_script_signal(const StringName &p_signal) const {
else if (base_cache.is_valid()) {
return base_cache->has_script_signal(p_signal);
}
-
#endif
return false;
}
diff --git a/modules/gdscript/gdscript.h b/modules/gdscript/gdscript.h
index f344beba9f..752d660ffb 100644
--- a/modules/gdscript/gdscript.h
+++ b/modules/gdscript/gdscript.h
@@ -141,7 +141,7 @@ protected:
static void _bind_methods();
public:
- bool is_valid() const { return valid; }
+ virtual bool is_valid() const { return valid; }
const Map<StringName, Ref<GDScript> > &get_subclasses() const { return subclasses; }
const Map<StringName, Variant> &get_constants() const { return constants; }
diff --git a/modules/gdscript/gdscript_compiler.cpp b/modules/gdscript/gdscript_compiler.cpp
index 45319c59e7..caa7fbfeca 100644
--- a/modules/gdscript/gdscript_compiler.cpp
+++ b/modules/gdscript/gdscript_compiler.cpp
@@ -132,7 +132,7 @@ GDScriptDataType GDScriptCompiler::_gdtype_from_datatype(const GDScriptParser::D
result.kind = GDScriptDataType::SCRIPT;
result.script_type = p_datatype.script_type;
result.native_type = result.script_type->get_instance_base_type();
- }
+ } break;
case GDScriptParser::DataType::GDSCRIPT: {
result.kind = GDScriptDataType::GDSCRIPT;
result.script_type = p_datatype.script_type;
@@ -1603,13 +1603,13 @@ Error GDScriptCompiler::_parse_block(CodeGen &codegen, const GDScriptParser::Blo
return OK;
}
-Error GDScriptCompiler::_parse_function(Ref<GDScript> p_script, const GDScriptParser::ClassNode *p_class, const GDScriptParser::FunctionNode *p_func, bool p_for_ready) {
+Error GDScriptCompiler::_parse_function(GDScript *p_script, const GDScriptParser::ClassNode *p_class, const GDScriptParser::FunctionNode *p_func, bool p_for_ready) {
Vector<int> bytecode;
CodeGen codegen;
codegen.class_node = p_class;
- codegen.script = p_script.ptr();
+ codegen.script = p_script;
codegen.function_node = p_func;
codegen.stack_max = 0;
codegen.current_line = 0;
@@ -1853,7 +1853,7 @@ Error GDScriptCompiler::_parse_function(Ref<GDScript> p_script, const GDScriptPa
return OK;
}
-Error GDScriptCompiler::_parse_class_level(Ref<GDScript> p_script, Ref<GDScript> p_owner, const GDScriptParser::ClassNode *p_class, bool p_keep_state) {
+Error GDScriptCompiler::_parse_class_level(GDScript *p_script, GDScript *p_owner, const GDScriptParser::ClassNode *p_class, bool p_keep_state) {
if (p_class->owner && p_class->owner->owner) {
// Owner is not root
@@ -1887,7 +1887,7 @@ Error GDScriptCompiler::_parse_class_level(Ref<GDScript> p_script, Ref<GDScript>
p_script->initializer = NULL;
p_script->subclasses.clear();
- p_script->_owner = p_owner.ptr();
+ p_script->_owner = p_owner;
p_script->tool = p_class->tool;
p_script->name = p_class->name;
@@ -1994,7 +1994,7 @@ Error GDScriptCompiler::_parse_class_level(Ref<GDScript> p_script, Ref<GDScript>
StringName name = p_class->_signals[i].name;
- GDScript *c = p_script.ptr();
+ GDScript *c = p_script;
while (c) {
@@ -2054,7 +2054,7 @@ Error GDScriptCompiler::_parse_class_level(Ref<GDScript> p_script, Ref<GDScript>
return OK;
}
-Error GDScriptCompiler::_parse_class_blocks(Ref<GDScript> p_script, const GDScriptParser::ClassNode *p_class, bool p_keep_state) {
+Error GDScriptCompiler::_parse_class_blocks(GDScript *p_script, const GDScriptParser::ClassNode *p_class, bool p_keep_state) {
//parse methods
bool has_initializer = false;
@@ -2159,7 +2159,7 @@ Error GDScriptCompiler::_parse_class_blocks(Ref<GDScript> p_script, const GDScri
return OK;
}
-void GDScriptCompiler::_make_scripts(const Ref<GDScript> p_script, const GDScriptParser::ClassNode *p_class, bool p_keep_state) {
+void GDScriptCompiler::_make_scripts(const GDScript *p_script, const GDScriptParser::ClassNode *p_class, bool p_keep_state) {
Map<StringName, Ref<GDScript> > old_subclasses;
@@ -2178,20 +2178,20 @@ void GDScriptCompiler::_make_scripts(const Ref<GDScript> p_script, const GDScrip
subclass.instance();
}
- subclass->_owner = const_cast<GDScript *>(p_script.ptr());
+ subclass->_owner = const_cast<GDScript *>(p_script);
class_map.insert(name, subclass);
_make_scripts(subclass.ptr(), p_class->subclasses[i], p_keep_state);
}
}
-Error GDScriptCompiler::compile(const GDScriptParser *p_parser, Ref<GDScript> p_script, bool p_keep_state) {
+Error GDScriptCompiler::compile(const GDScriptParser *p_parser, GDScript *p_script, bool p_keep_state) {
err_line = -1;
err_column = -1;
error = "";
parser = p_parser;
- main_script = p_script.ptr();
+ main_script = p_script;
const GDScriptParser::Node *root = parser->get_parse_tree();
ERR_FAIL_COND_V(root->type != GDScriptParser::Node::TYPE_CLASS, ERR_INVALID_DATA);
diff --git a/modules/gdscript/gdscript_compiler.h b/modules/gdscript/gdscript_compiler.h
index 23c6450aa7..55f5e2b48e 100644
--- a/modules/gdscript/gdscript_compiler.h
+++ b/modules/gdscript/gdscript_compiler.h
@@ -148,17 +148,17 @@ class GDScriptCompiler {
int _parse_assign_right_expression(CodeGen &codegen, const GDScriptParser::OperatorNode *p_expression, int p_stack_level);
int _parse_expression(CodeGen &codegen, const GDScriptParser::Node *p_expression, int p_stack_level, bool p_root = false, bool p_initializer = false);
Error _parse_block(CodeGen &codegen, const GDScriptParser::BlockNode *p_block, int p_stack_level = 0, int p_break_addr = -1, int p_continue_addr = -1);
- Error _parse_function(Ref<GDScript> p_script, const GDScriptParser::ClassNode *p_class, const GDScriptParser::FunctionNode *p_func, bool p_for_ready = false);
- Error _parse_class_level(Ref<GDScript> p_script, Ref<GDScript> p_owner, const GDScriptParser::ClassNode *p_class, bool p_keep_state);
- Error _parse_class_blocks(Ref<GDScript> p_script, const GDScriptParser::ClassNode *p_class, bool p_keep_state);
- void _make_scripts(const Ref<GDScript> p_script, const GDScriptParser::ClassNode *p_class, bool p_keep_state);
+ Error _parse_function(GDScript *p_script, const GDScriptParser::ClassNode *p_class, const GDScriptParser::FunctionNode *p_func, bool p_for_ready = false);
+ Error _parse_class_level(GDScript *p_script, GDScript *p_owner, const GDScriptParser::ClassNode *p_class, bool p_keep_state);
+ Error _parse_class_blocks(GDScript *p_script, const GDScriptParser::ClassNode *p_class, bool p_keep_state);
+ void _make_scripts(const GDScript *p_script, const GDScriptParser::ClassNode *p_class, bool p_keep_state);
int err_line;
int err_column;
StringName source;
String error;
public:
- Error compile(const GDScriptParser *p_parser, Ref<GDScript> p_script, bool p_keep_state = false);
+ Error compile(const GDScriptParser *p_parser, GDScript *p_script, bool p_keep_state = false);
String get_error() const;
int get_error_line() const;
diff --git a/modules/gdscript/gdscript_function.cpp b/modules/gdscript/gdscript_function.cpp
index c67cf124c0..cd6c21a629 100644
--- a/modules/gdscript/gdscript_function.cpp
+++ b/modules/gdscript/gdscript_function.cpp
@@ -370,7 +370,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
}
script = p_instance->script.ptr();
} else {
- script = this->_script.ptr();
+ script = _script;
}
}
@@ -1182,7 +1182,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
GET_VARIANT_PTR(dst, argc + 3);
- const GDScript *gds = _script.ptr();
+ const GDScript *gds = _script;
const Map<StringName, GDScriptFunction *>::Element *E = NULL;
while (gds->base.ptr()) {
@@ -1253,7 +1253,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
gdfs->state.stack_size = _stack_size;
gdfs->state.self = self;
gdfs->state.alloca_size = alloca_size;
- gdfs->state.script = _script;
+ gdfs->state.script = Ref<GDScript>(_script);
gdfs->state.ip = ip + ipofs;
gdfs->state.line = line;
gdfs->state.instance_id = (p_instance && p_instance->get_owner()) ? p_instance->get_owner()->get_instance_id() : 0;
@@ -1760,22 +1760,14 @@ GDScriptFunction::~GDScriptFunction() {
Variant GDScriptFunctionState::_signal_callback(const Variant **p_args, int p_argcount, Variant::CallError &r_error) {
-#ifdef DEBUG_ENABLED
- // Checking this first since it's faster
- if (!state.script.is_valid()) {
- ERR_EXPLAIN("Resumed after yield, but script is gone");
- ERR_FAIL_V(Variant());
- }
-
if (state.instance_id && !ObjectDB::get_instance(state.instance_id)) {
+#ifdef DEBUG_ENABLED
ERR_EXPLAIN("Resumed after yield, but class instance is gone");
ERR_FAIL_V(Variant());
- }
#else
- if (!is_valid()) {
return Variant();
- }
#endif
+ }
Variant arg;
r_error.error = Variant::CallError::CALL_OK;
@@ -1842,9 +1834,6 @@ bool GDScriptFunctionState::is_valid(bool p_extended_check) const {
return false;
if (p_extended_check) {
- //script gone? (checking this first since it's faster)
- if (!state.script.is_valid())
- return false;
//class instance gone?
if (state.instance_id && !ObjectDB::get_instance(state.instance_id))
return false;
@@ -1856,18 +1845,14 @@ bool GDScriptFunctionState::is_valid(bool p_extended_check) const {
Variant GDScriptFunctionState::resume(const Variant &p_arg) {
ERR_FAIL_COND_V(!function, Variant());
-#ifdef DEBUG_ENABLED
- // Checking this first since it's faster
- if (!state.script.is_valid()) {
- ERR_EXPLAIN("Resumed after yield, but script is gone");
- ERR_FAIL_V(Variant());
- }
-
if (state.instance_id && !ObjectDB::get_instance(state.instance_id)) {
+#ifdef DEBUG_ENABLED
ERR_EXPLAIN("Resumed after yield, but class instance is gone");
ERR_FAIL_V(Variant());
- }
+#else
+ return Variant();
#endif
+ }
state.result = p_arg;
Variant::CallError err;
diff --git a/modules/gdscript/gdscript_function.h b/modules/gdscript/gdscript_function.h
index a47070de4f..5509edf24a 100644
--- a/modules/gdscript/gdscript_function.h
+++ b/modules/gdscript/gdscript_function.h
@@ -225,7 +225,7 @@ private:
bool _static;
MultiplayerAPI::RPCMode rpc_mode;
- Ref<GDScript> _script;
+ GDScript *_script;
StringName name;
Vector<Variant> constants;
@@ -297,7 +297,7 @@ public:
int get_default_argument_addr(int p_idx) const;
GDScriptDataType get_return_type() const;
GDScriptDataType get_argument_type(int p_idx) const;
- GDScript *get_script() const { return const_cast<GDScript *>(_script.ptr()); }
+ GDScript *get_script() const { return _script; }
StringName get_source() const { return source; }
void debug_get_stack_member_state(int p_line, List<Pair<StringName, int> > *r_stackvars) const;
diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp
index a4bda42b16..0926c1a1ab 100644
--- a/modules/gdscript/gdscript_parser.cpp
+++ b/modules/gdscript/gdscript_parser.cpp
@@ -3752,6 +3752,19 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
BlockNode *block = alloc_node<BlockNode>();
block->parent_class = p_class;
+ FunctionNode *function = alloc_node<FunctionNode>();
+ function->name = name;
+ function->arguments = arguments;
+ function->argument_types = argument_types;
+ function->default_values = default_values;
+ function->_static = _static;
+ function->line = fnline;
+#ifdef DEBUG_ENABLED
+ function->arguments_usage = arguments_usage;
+#endif // DEBUG_ENABLED
+ function->rpc_mode = rpc_mode;
+ rpc_mode = MultiplayerAPI::RPC_MODE_DISABLED;
+
if (name == "_init") {
if (_static) {
@@ -3782,7 +3795,9 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
parenthesis++;
while (true) {
+ current_function = function;
Node *arg = _parse_and_reduce_expression(p_class, _static);
+ current_function = NULL;
cparent->arguments.push_back(arg);
if (tokenizer->get_token() == GDScriptTokenizer::TK_COMMA) {
@@ -3826,19 +3841,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
return;
}
- FunctionNode *function = alloc_node<FunctionNode>();
- function->name = name;
function->return_type = return_type;
- function->arguments = arguments;
- function->argument_types = argument_types;
- function->default_values = default_values;
- function->_static = _static;
- function->line = fnline;
-#ifdef DEBUG_ENABLED
- function->arguments_usage = arguments_usage;
-#endif // DEBUG_ENABLED
- function->rpc_mode = rpc_mode;
- rpc_mode = MultiplayerAPI::RPC_MODE_DISABLED;
if (_static)
p_class->static_functions.push_back(function);