summaryrefslogtreecommitdiff
path: root/modules/gdscript
diff options
context:
space:
mode:
Diffstat (limited to 'modules/gdscript')
-rw-r--r--modules/gdscript/editor/gdscript_highlighter.cpp4
-rw-r--r--modules/gdscript/editor/gdscript_highlighter.h4
-rw-r--r--modules/gdscript/gdscript.cpp65
-rw-r--r--modules/gdscript/gdscript.h9
-rw-r--r--modules/gdscript/gdscript_compiler.cpp8
-rw-r--r--modules/gdscript/gdscript_compiler.h4
-rw-r--r--modules/gdscript/gdscript_editor.cpp48
-rw-r--r--modules/gdscript/gdscript_function.cpp6
-rw-r--r--modules/gdscript/gdscript_function.h27
-rw-r--r--modules/gdscript/gdscript_functions.cpp7
-rw-r--r--modules/gdscript/gdscript_functions.h4
-rw-r--r--modules/gdscript/gdscript_parser.cpp146
-rw-r--r--modules/gdscript/gdscript_parser.h8
-rw-r--r--modules/gdscript/gdscript_tokenizer.cpp4
-rw-r--r--modules/gdscript/gdscript_tokenizer.h6
-rw-r--r--modules/gdscript/register_types.cpp80
-rw-r--r--modules/gdscript/register_types.h4
17 files changed, 291 insertions, 143 deletions
diff --git a/modules/gdscript/editor/gdscript_highlighter.cpp b/modules/gdscript/editor/gdscript_highlighter.cpp
index e4aee842ba..4f59b06ae6 100644
--- a/modules/gdscript/editor/gdscript_highlighter.cpp
+++ b/modules/gdscript/editor/gdscript_highlighter.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/gdscript/editor/gdscript_highlighter.h b/modules/gdscript/editor/gdscript_highlighter.h
index b8cb4a65e9..9dc10a5d1b 100644
--- a/modules/gdscript/editor/gdscript_highlighter.h
+++ b/modules/gdscript/editor/gdscript_highlighter.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/gdscript/gdscript.cpp b/modules/gdscript/gdscript.cpp
index 538249c8e2..f29432666e 100644
--- a/modules/gdscript/gdscript.cpp
+++ b/modules/gdscript/gdscript.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -223,16 +223,21 @@ void GDScript::_placeholder_erased(PlaceHolderScriptInstance *p_placeholder) {
void GDScript::get_script_method_list(List<MethodInfo> *p_list) const {
- for (const Map<StringName, GDScriptFunction *>::Element *E = member_functions.front(); E; E = E->next()) {
- GDScriptFunction *func = E->get();
- MethodInfo mi;
- mi.name = E->key();
- for (int i = 0; i < func->get_argument_count(); i++) {
- mi.arguments.push_back(func->get_argument_type(i));
+ const GDScript *current = this;
+ while (current) {
+ for (const Map<StringName, GDScriptFunction *>::Element *E = member_functions.front(); E; E = E->next()) {
+ GDScriptFunction *func = E->get();
+ MethodInfo mi;
+ mi.name = E->key();
+ for (int i = 0; i < func->get_argument_count(); i++) {
+ mi.arguments.push_back(func->get_argument_type(i));
+ }
+
+ mi.return_val = func->get_return_type();
+ p_list->push_back(mi);
}
- mi.return_val = func->get_return_type();
- p_list->push_back(mi);
+ current = current->_base;
}
}
@@ -475,20 +480,15 @@ bool GDScript::_update_exports() {
_signals[c->_signals[i].name] = c->_signals[i].arguments;
}
} else {
- for (Set<PlaceHolderScriptInstance *>::Element *E = placeholders.front(); E; E = E->next()) {
- E->get()->set_build_failed(true);
- }
- return false;
- }
- } else {
- if (!valid) {
- for (Set<PlaceHolderScriptInstance *>::Element *E = placeholders.front(); E; E = E->next()) {
- E->get()->set_build_failed(true);
- }
+ placeholder_fallback_enabled = true;
return false;
}
+ } else if (placeholder_fallback_enabled) {
+ return false;
}
+ placeholder_fallback_enabled = false;
+
if (base_cache.is_valid()) {
if (base_cache->_update_exports()) {
changed = true;
@@ -503,7 +503,6 @@ bool GDScript::_update_exports() {
_update_exports_values(values, propnames);
for (Set<PlaceHolderScriptInstance *>::Element *E = placeholders.front(); E; E = E->next()) {
- E->get()->set_build_failed(false);
E->get()->update(propnames, values);
}
}
@@ -648,7 +647,8 @@ Variant GDScript::call(const StringName &p_method, const Variant **p_args, int p
if (E) {
if (!E->get()->is_static()) {
- WARN_PRINT(String("Can't call non-static function: '" + String(p_method) + "' in script.").utf8().get_data());
+ ERR_EXPLAIN("Can't call non-static function: '" + String(p_method) + "' in script.");
+ ERR_FAIL_V(Variant());
}
return E->get()->call(NULL, p_args, p_argcount, r_error);
@@ -907,6 +907,7 @@ GDScript::GDScript() :
tool = false;
#ifdef TOOLS_ENABLED
source_changed_cache = false;
+ placeholder_fallback_enabled = false;
#endif
#ifdef DEBUG_ENABLED
@@ -1675,6 +1676,8 @@ void GDScriptLanguage::reload_tool_script(const Ref<Script> &p_script, bool p_so
//restore state if saved
for (Map<ObjectID, List<Pair<StringName, Variant> > >::Element *F = E->get().front(); F; F = F->next()) {
+ List<Pair<StringName, Variant> > &saved_state = F->get();
+
Object *obj = ObjectDB::get_instance(F->key());
if (!obj)
continue;
@@ -1684,16 +1687,26 @@ void GDScriptLanguage::reload_tool_script(const Ref<Script> &p_script, bool p_so
obj->set_script(RefPtr());
}
obj->set_script(scr.get_ref_ptr());
- if (!obj->get_script_instance()) {
+
+ ScriptInstance *script_instance = obj->get_script_instance();
+
+ if (!script_instance) {
//failed, save reload state for next time if not saved
if (!scr->pending_reload_state.has(obj->get_instance_id())) {
- scr->pending_reload_state[obj->get_instance_id()] = F->get();
+ scr->pending_reload_state[obj->get_instance_id()] = saved_state;
}
continue;
}
- for (List<Pair<StringName, Variant> >::Element *G = F->get().front(); G; G = G->next()) {
- obj->get_script_instance()->set(G->get().first, G->get().second);
+ if (script_instance->is_placeholder() && scr->is_placeholder_fallback_enabled()) {
+ PlaceHolderScriptInstance *placeholder = static_cast<PlaceHolderScriptInstance *>(script_instance);
+ for (List<Pair<StringName, Variant> >::Element *G = saved_state.front(); G; G = G->next()) {
+ placeholder->property_set_fallback(G->get().first, G->get().second);
+ }
+ } else {
+ for (List<Pair<StringName, Variant> >::Element *G = saved_state.front(); G; G = G->next()) {
+ script_instance->set(G->get().first, G->get().second);
+ }
}
scr->pending_reload_state.erase(obj->get_instance_id()); //as it reloaded, remove pending state
diff --git a/modules/gdscript/gdscript.h b/modules/gdscript/gdscript.h
index 3e7cb076aa..86c00c0b59 100644
--- a/modules/gdscript/gdscript.h
+++ b/modules/gdscript/gdscript.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -97,6 +97,7 @@ class GDScript : public Script {
Ref<GDScript> base_cache;
Set<ObjectID> inheriters_cache;
bool source_changed_cache;
+ bool placeholder_fallback_enabled;
void _update_exports_values(Map<StringName, Variant> &values, List<PropertyInfo> &propnames);
#endif
@@ -209,6 +210,10 @@ public:
virtual void get_constants(Map<StringName, Variant> *p_constants);
virtual void get_members(Set<StringName> *p_members);
+#ifdef TOOLS_ENABLED
+ virtual bool is_placeholder_fallback_enabled() const { return placeholder_fallback_enabled; }
+#endif
+
GDScript();
~GDScript();
};
diff --git a/modules/gdscript/gdscript_compiler.cpp b/modules/gdscript/gdscript_compiler.cpp
index caa7fbfeca..e59b57b39a 100644
--- a/modules/gdscript/gdscript_compiler.cpp
+++ b/modules/gdscript/gdscript_compiler.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -486,7 +486,7 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser::
script = codegen.script;
} else {
StringName name = cn->cast_type.class_type->name;
- if (class_map[name] == codegen.script->subclasses[name]) {
+ if (codegen.script->subclasses.has(name) && class_map[name] == codegen.script->subclasses[name]) {
idx = codegen.get_name_map_pos(name);
idx |= GDScriptFunction::ADDR_TYPE_CLASS_CONSTANT << GDScriptFunction::ADDR_BITS;
} else {
@@ -1183,7 +1183,7 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser::
script = codegen.script;
} else {
StringName name = assign_type.class_type->name;
- if (class_map[name] == codegen.script->subclasses[name]) {
+ if (codegen.script->subclasses.has(name) && class_map[name] == codegen.script->subclasses[name]) {
idx = codegen.get_name_map_pos(name);
idx |= GDScriptFunction::ADDR_TYPE_CLASS_CONSTANT << GDScriptFunction::ADDR_BITS;
} else {
diff --git a/modules/gdscript/gdscript_compiler.h b/modules/gdscript/gdscript_compiler.h
index 55f5e2b48e..8440807a56 100644
--- a/modules/gdscript/gdscript_compiler.h
+++ b/modules/gdscript/gdscript_compiler.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/gdscript/gdscript_editor.cpp b/modules/gdscript/gdscript_editor.cpp
index 068e8d2d92..af770ac533 100644
--- a/modules/gdscript/gdscript_editor.cpp
+++ b/modules/gdscript/gdscript_editor.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -479,12 +479,15 @@ struct GDScriptCompletionContext {
Object *base;
String base_path;
int line;
+ uint32_t depth;
GDScriptCompletionContext() :
_class(NULL),
function(NULL),
block(NULL),
- base(NULL) {}
+ base(NULL),
+ line(0),
+ depth(0) {}
};
struct GDScriptCompletionIdentifier {
@@ -615,6 +618,9 @@ static GDScriptCompletionIdentifier _type_from_gdtype(const GDScriptDataType &p_
ci.type.script_type = p_gdtype.script_type;
switch (p_gdtype.kind) {
+ case GDScriptDataType::UNINITIALIZED: {
+ ERR_EXPLAIN("Uninitialized completion. Please report a bug.");
+ } break;
case GDScriptDataType::BUILTIN: {
ci.type.kind = GDScriptParser::DataType::BUILTIN;
} break;
@@ -631,12 +637,18 @@ static GDScriptCompletionIdentifier _type_from_gdtype(const GDScriptDataType &p_
return ci;
}
-static bool _guess_identifier_type(const GDScriptCompletionContext &p_context, const StringName &p_identifier, GDScriptCompletionIdentifier &r_type);
-static bool _guess_identifier_type_from_base(const GDScriptCompletionContext &p_context, const GDScriptCompletionIdentifier &p_base, const StringName &p_identifier, GDScriptCompletionIdentifier &r_type);
-static bool _guess_method_return_type_from_base(const GDScriptCompletionContext &p_context, const GDScriptCompletionIdentifier &p_base, const StringName &p_method, GDScriptCompletionIdentifier &r_type);
+static bool _guess_identifier_type(GDScriptCompletionContext &p_context, const StringName &p_identifier, GDScriptCompletionIdentifier &r_type);
+static bool _guess_identifier_type_from_base(GDScriptCompletionContext &p_context, const GDScriptCompletionIdentifier &p_base, const StringName &p_identifier, GDScriptCompletionIdentifier &r_type);
+static bool _guess_method_return_type_from_base(GDScriptCompletionContext &p_context, const GDScriptCompletionIdentifier &p_base, const StringName &p_method, GDScriptCompletionIdentifier &r_type);
-static bool _guess_expression_type(const GDScriptCompletionContext &p_context, const GDScriptParser::Node *p_expression, GDScriptCompletionIdentifier &r_type) {
+static bool _guess_expression_type(GDScriptCompletionContext &p_context, const GDScriptParser::Node *p_expression, GDScriptCompletionIdentifier &r_type) {
bool found = false;
+
+ if (++p_context.depth > 100) {
+ print_error("Maximum _guess_expression_type depth limit reached. Please file a bugreport.");
+ return false;
+ }
+
switch (p_expression->type) {
case GDScriptParser::Node::TYPE_CONSTANT: {
const GDScriptParser::ConstantNode *cn = static_cast<const GDScriptParser::ConstantNode *>(p_expression);
@@ -1125,7 +1137,7 @@ static bool _guess_expression_type(const GDScriptCompletionContext &p_context, c
return found;
}
-static bool _guess_identifier_type(const GDScriptCompletionContext &p_context, const StringName &p_identifier, GDScriptCompletionIdentifier &r_type) {
+static bool _guess_identifier_type(GDScriptCompletionContext &p_context, const StringName &p_identifier, GDScriptCompletionIdentifier &r_type) {
// Look in blocks first
const GDScriptParser::BlockNode *blk = p_context.block;
@@ -1181,7 +1193,11 @@ static bool _guess_identifier_type(const GDScriptCompletionContext &p_context, c
c.line = op->line;
c.block = blk;
if (_guess_expression_type(p_context, op->arguments[1], r_type)) {
- r_type.type.is_meta_type = false;
+ r_type.type.is_meta_type = false; // Right-hand of `is` will be a meta type, but the left-hand value is not
+ // Not an assignment, it shouldn't carry any value
+ r_type.value = Variant();
+ r_type.assigned_expression = NULL;
+
return true;
}
}
@@ -1351,7 +1367,7 @@ static bool _guess_identifier_type(const GDScriptCompletionContext &p_context, c
return false;
}
-static bool _guess_identifier_type_from_base(const GDScriptCompletionContext &p_context, const GDScriptCompletionIdentifier &p_base, const StringName &p_identifier, GDScriptCompletionIdentifier &r_type) {
+static bool _guess_identifier_type_from_base(GDScriptCompletionContext &p_context, const GDScriptCompletionIdentifier &p_base, const StringName &p_identifier, GDScriptCompletionIdentifier &r_type) {
GDScriptParser::DataType base_type = p_base.type;
bool _static = base_type.is_meta_type;
while (base_type.has_type) {
@@ -1540,7 +1556,7 @@ static bool _find_last_return_in_block(const GDScriptCompletionContext &p_contex
return false;
}
-static bool _guess_method_return_type_from_base(const GDScriptCompletionContext &p_context, const GDScriptCompletionIdentifier &p_base, const StringName &p_method, GDScriptCompletionIdentifier &r_type) {
+static bool _guess_method_return_type_from_base(GDScriptCompletionContext &p_context, const GDScriptCompletionIdentifier &p_base, const StringName &p_method, GDScriptCompletionIdentifier &r_type) {
GDScriptParser::DataType base_type = p_base.type;
bool _static = base_type.is_meta_type;
@@ -2305,7 +2321,7 @@ static void _find_call_arguments(const GDScriptCompletionContext &p_context, con
}
}
-static void _find_call_arguments(const GDScriptCompletionContext &p_context, const GDScriptParser::Node *p_node, int p_argidx, Set<String> &r_result, bool &r_forced, String &r_arghint) {
+static void _find_call_arguments(GDScriptCompletionContext &p_context, const GDScriptParser::Node *p_node, int p_argidx, Set<String> &r_result, bool &r_forced, String &r_arghint) {
if (!p_node || p_node->type != GDScriptParser::Node::TYPE_OPERATOR) {
return;
@@ -2442,9 +2458,13 @@ Error GDScriptLanguage::complete_code(const String &p_code, const String &p_base
context._class = parser.get_completion_class();
context.block = parser.get_completion_block();
context.function = parser.get_completion_function();
- context.base = p_owner;
- context.base_path = p_base_path;
context.line = parser.get_completion_line();
+
+ if (!context._class || context._class->owner == NULL) {
+ context.base = p_owner;
+ context.base_path = p_base_path;
+ }
+
bool is_function = false;
switch (parser.get_completion_type()) {
diff --git a/modules/gdscript/gdscript_function.cpp b/modules/gdscript/gdscript_function.cpp
index cd6c21a629..98871ddec3 100644
--- a/modules/gdscript/gdscript_function.cpp
+++ b/modules/gdscript/gdscript_function.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -1083,7 +1083,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
if (argc >= 1) {
methodstr = String(*argptrs[0]) + " (via call)";
if (err.error == Variant::CallError::CALL_ERROR_INVALID_ARGUMENT) {
- err.argument -= 1;
+ err.argument += 1;
}
}
} else if (methodstr == "free") {
diff --git a/modules/gdscript/gdscript_function.h b/modules/gdscript/gdscript_function.h
index 5509edf24a..cefc28d77f 100644
--- a/modules/gdscript/gdscript_function.h
+++ b/modules/gdscript/gdscript_function.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -36,7 +36,7 @@
#include "core/reference.h"
#include "core/script_language.h"
#include "core/self_list.h"
-#include "core/string_db.h"
+#include "core/string_name.h"
#include "core/variant.h"
class GDScriptInstance;
@@ -45,10 +45,11 @@ class GDScript;
struct GDScriptDataType {
bool has_type;
enum {
+ UNINITIALIZED,
BUILTIN,
NATIVE,
SCRIPT,
- GDSCRIPT
+ GDSCRIPT,
} kind;
Variant::Type builtin_type;
StringName native_type;
@@ -58,6 +59,8 @@ struct GDScriptDataType {
if (!has_type) return true; // Can't type check
switch (kind) {
+ case UNINITIALIZED:
+ break;
case BUILTIN: {
Variant::Type var_type = p_variant.get_type();
bool valid = builtin_type == var_type;
@@ -74,8 +77,14 @@ struct GDScriptDataType {
return false;
}
Object *obj = p_variant.operator Object *();
- if (obj && !ClassDB::is_parent_class(obj->get_class_name(), native_type)) {
- return false;
+ if (obj) {
+ if (!ClassDB::is_parent_class(obj->get_class_name(), native_type)) {
+ // Try with underscore prefix
+ StringName underscore_native_type = "_" + native_type;
+ if (!ClassDB::is_parent_class(obj->get_class_name(), underscore_native_type)) {
+ return false;
+ }
+ }
}
return true;
} break;
@@ -107,6 +116,8 @@ struct GDScriptDataType {
PropertyInfo info;
if (has_type) {
switch (kind) {
+ case UNINITIALIZED:
+ break;
case BUILTIN: {
info.type = builtin_type;
} break;
@@ -128,7 +139,9 @@ struct GDScriptDataType {
}
GDScriptDataType() :
- has_type(false) {}
+ has_type(false),
+ kind(UNINITIALIZED),
+ builtin_type(Variant::NIL) {}
};
class GDScriptFunction {
diff --git a/modules/gdscript/gdscript_functions.cpp b/modules/gdscript/gdscript_functions.cpp
index 2485e6f04a..44d44462ca 100644
--- a/modules/gdscript/gdscript_functions.cpp
+++ b/modules/gdscript/gdscript_functions.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -1565,7 +1565,8 @@ MethodInfo GDScriptFunctions::get_info(Function p_func) {
} break;
case MATH_LERP: {
MethodInfo mi("lerp", PropertyInfo(Variant::NIL, "from"), PropertyInfo(Variant::NIL, "to"), PropertyInfo(Variant::REAL, "weight"));
- mi.return_val.type = Variant::REAL;
+ mi.return_val.type = Variant::NIL;
+ mi.return_val.usage |= PROPERTY_USAGE_NIL_IS_VARIANT;
return mi;
} break;
case MATH_INVERSE_LERP: {
diff --git a/modules/gdscript/gdscript_functions.h b/modules/gdscript/gdscript_functions.h
index 33d5f27230..fcb8f32e54 100644
--- a/modules/gdscript/gdscript_functions.h
+++ b/modules/gdscript/gdscript_functions.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp
index 6ea0dbcb19..b53d37226c 100644
--- a/modules/gdscript/gdscript_parser.cpp
+++ b/modules/gdscript/gdscript_parser.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -811,6 +811,21 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
expr = constant;
bfn = true;
}
+
+ // Check parents for the constant
+ if (!bfn && cln->extends_file != StringName()) {
+ Ref<GDScript> parent = ResourceLoader::load(cln->extends_file);
+ if (parent.is_valid() && parent->is_valid()) {
+ Map<StringName, Variant> parent_constants;
+ parent->get_constants(&parent_constants);
+ if (parent_constants.has(identifier)) {
+ ConstantNode *constant = alloc_node<ConstantNode>();
+ constant->value = parent_constants[identifier];
+ expr = constant;
+ bfn = true;
+ }
+ }
+ }
}
if (!bfn) {
@@ -3479,16 +3494,20 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
tokenizer->advance();
if ((tokenizer->get_token() == GDScriptTokenizer::TK_CONSTANT && tokenizer->get_token_constant().get_type() == Variant::STRING)) {
- Variant constant = tokenizer->get_token_constant();
- String icon_path = constant.operator String();
+#ifdef TOOLS_ENABLED
+ if (Engine::get_singleton()->is_editor_hint()) {
+ Variant constant = tokenizer->get_token_constant();
+ String icon_path = constant.operator String();
- String abs_icon_path = icon_path.is_rel_path() ? self_path.get_base_dir().plus_file(icon_path).simplify_path() : icon_path;
- if (!FileAccess::exists(abs_icon_path)) {
- _set_error("No class icon found at: " + abs_icon_path);
- return;
- }
+ String abs_icon_path = icon_path.is_rel_path() ? self_path.get_base_dir().plus_file(icon_path).simplify_path() : icon_path;
+ if (!FileAccess::exists(abs_icon_path)) {
+ _set_error("No class icon found at: " + abs_icon_path);
+ return;
+ }
- p_class->icon_path = icon_path;
+ p_class->icon_path = icon_path;
+ }
+#endif
tokenizer->advance();
} else {
@@ -4538,6 +4557,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
//variale declaration and (eventual) initialization
ClassNode::Member member;
+
bool autoexport = tokenizer->get_token(-1) == GDScriptTokenizer::TK_PR_EXPORT;
if (current_export.type != Variant::NIL) {
member._export = current_export;
@@ -4559,6 +4579,10 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
member.line = tokenizer->get_token_line();
member.usages = 0;
member.rpc_mode = rpc_mode;
+#ifdef TOOLS_ENABLED
+ Variant::CallError ce;
+ member.default_value = Variant::construct(member._export.type, NULL, 0, ce);
+#endif
if (current_class->constant_expressions.has(member.identifier)) {
_set_error("A constant named '" + String(member.identifier) + "' already exists in this class (at line: " +
@@ -4663,7 +4687,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
}
}
#ifdef TOOLS_ENABLED
- if (subexpr->type == Node::TYPE_CONSTANT && member._export.type != Variant::NIL) {
+ if (subexpr->type == Node::TYPE_CONSTANT && (member._export.type != Variant::NIL || member.data_type.has_type)) {
ConstantNode *cn = static_cast<ConstantNode *>(subexpr);
if (cn->value.get_type() != Variant::NIL) {
@@ -4701,6 +4725,25 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
_set_error("Type-less export needs a constant expression assigned to infer type.");
return;
}
+
+ if (member._export.type != Variant::NIL) {
+ IdentifierNode *id = alloc_node<IdentifierNode>();
+ id->name = member.identifier;
+
+ ConstantNode *cn = alloc_node<ConstantNode>();
+
+ Variant::CallError ce;
+ cn->value = Variant::construct(member._export.type, NULL, 0, ce);
+
+ OperatorNode *op = alloc_node<OperatorNode>();
+ op->op = OperatorNode::OP_INIT_ASSIGN;
+ op->arguments.push_back(id);
+ op->arguments.push_back(cn);
+
+ p_class->initializer->statements.push_back(op);
+
+ member.initial_assignment = op;
+ }
}
if (autoexport && member.data_type.has_type) {
@@ -5058,7 +5101,7 @@ void GDScriptParser::_determine_inheritance(ClassNode *p_class) {
if (ScriptServer::is_global_class(base)) {
base_script = ResourceLoader::load(ScriptServer::get_global_class_path(base));
if (!base_script.is_valid()) {
- _set_error("Class '" + base + "' could not be fully loaded (script error or cyclic inheritance).", p_class->line);
+ _set_error("Class '" + base + "' could not be fully loaded (script error or cyclic dependency).", p_class->line);
return;
}
p = NULL;
@@ -5387,7 +5430,7 @@ GDScriptParser::DataType GDScriptParser::_resolve_type(const DataType &p_source,
Ref<GDScript> gds = script;
if (gds.is_valid()) {
if (!gds->is_valid()) {
- _set_error("Class '" + id + "' could not be fully loaded (script error or cyclic inheritance).", p_line);
+ _set_error("Class '" + id + "' could not be fully loaded (script error or cyclic dependency).", p_line);
return DataType();
}
result.kind = DataType::GDSCRIPT;
@@ -5434,6 +5477,12 @@ GDScriptParser::DataType GDScriptParser::_resolve_type(const DataType &p_source,
// Inner classes
ClassNode *outer_class = p;
while (outer_class) {
+ if (outer_class->name == id) {
+ found = true;
+ result.kind = DataType::CLASS;
+ result.class_type = outer_class;
+ break;
+ }
for (int i = 0; i < outer_class->subclasses.size(); i++) {
if (outer_class->subclasses[i] == p) {
continue;
@@ -5569,6 +5618,9 @@ GDScriptParser::DataType GDScriptParser::_type_from_gdtype(const GDScriptDataTyp
result.script_type = p_gdtype.script_type;
switch (p_gdtype.kind) {
+ case GDScriptDataType::UNINITIALIZED: {
+ ERR_EXPLAIN("Uninitialized datatype. Please report a bug.");
+ } break;
case GDScriptDataType::BUILTIN: {
result.kind = DataType::BUILTIN;
} break;
@@ -5932,7 +5984,7 @@ GDScriptParser::DataType GDScriptParser::_reduce_node_type(Node *p_node) {
int idx = current_function->arguments.find(id->name);
node_type = current_function->argument_types[idx];
} else {
- node_type = _reduce_identifier_type(NULL, id->name, id->line);
+ node_type = _reduce_identifier_type(NULL, id->name, id->line, false);
}
} break;
case Node::TYPE_CAST: {
@@ -6182,7 +6234,7 @@ GDScriptParser::DataType GDScriptParser::_reduce_node_type(Node *p_node) {
result.is_constant = false;
node_type = result;
} else {
- node_type = _reduce_identifier_type(&base_type, member_id->name, op->line);
+ node_type = _reduce_identifier_type(&base_type, member_id->name, op->line, true);
#ifdef DEBUG_ENABLED
if (!node_type.has_type) {
_add_warning(GDScriptWarning::UNSAFE_PROPERTY_ACCESS, op->line, member_id->name.operator String(), base_type.to_string());
@@ -6224,7 +6276,7 @@ GDScriptParser::DataType GDScriptParser::_reduce_node_type(Node *p_node) {
if (check_types && index_type.has_type) {
if (base_type.kind == DataType::BUILTIN) {
// Check if indexing is valid
- bool error = index_type.kind != DataType::BUILTIN;
+ bool error = index_type.kind != DataType::BUILTIN && base_type.builtin_type != Variant::DICTIONARY;
if (!error) {
switch (base_type.builtin_type) {
// Expect int or real as index
@@ -6767,10 +6819,10 @@ GDScriptParser::DataType GDScriptParser::_reduce_function_call_type(const Operat
valid = _get_function_signature(base_type, callee_name, return_type, arg_types,
default_args_count, is_static, is_vararg);
- if (valid) {
- return_type = original_type;
- return_type.is_meta_type = false;
- }
+ return_type = original_type;
+ return_type.is_meta_type = false;
+
+ valid = true; // There's always an initializer, we can assume this is true
}
if (!valid) {
@@ -6829,6 +6881,7 @@ GDScriptParser::DataType GDScriptParser::_reduce_function_call_type(const Operat
} break;
}
+#ifdef DEBUG_ENABLED
if (!check_types) {
return return_type;
}
@@ -6854,11 +6907,9 @@ GDScriptParser::DataType GDScriptParser::_reduce_function_call_type(const Operat
if (!par_type.has_type) {
_mark_line_as_unsafe(p_call->line);
-#ifdef DEBUG_ENABLED
if (par_type.may_yield && p_call->arguments[i]->type == Node::TYPE_OPERATOR) {
_add_warning(GDScriptWarning::FUNCTION_MAY_YIELD, p_call->line, _find_function_name(static_cast<OperatorNode *>(p_call->arguments[i])));
}
-#endif // DEBUG_ENABLED
} else if (!_is_type_compatible(arg_types[i - arg_diff], par_type, true)) {
// Supertypes are acceptable for dynamic compliance
if (!_is_type_compatible(par_type, arg_types[i - arg_diff])) {
@@ -6871,14 +6922,14 @@ GDScriptParser::DataType GDScriptParser::_reduce_function_call_type(const Operat
_mark_line_as_unsafe(p_call->line);
}
} else {
-#ifdef DEBUG_ENABLED
if (arg_type.kind == DataType::BUILTIN && arg_type.builtin_type == Variant::INT && par_type.kind == DataType::BUILTIN && par_type.builtin_type == Variant::REAL) {
_add_warning(GDScriptWarning::NARROWING_CONVERSION, p_call->line, callee_name);
}
-#endif // DEBUG_ENABLED
}
}
+#endif // DEBUG_ENABLED
+
return return_type;
}
@@ -6899,9 +6950,9 @@ bool GDScriptParser::_get_member_type(const DataType &p_base_type, const StringN
if (!base_type.is_meta_type) {
for (int i = 0; i < base->variables.size(); i++) {
- ClassNode::Member m = base->variables[i];
- if (m.identifier == p_member) {
- r_member_type = m.data_type;
+ if (base->variables[i].identifier == p_member) {
+ r_member_type = base->variables[i].data_type;
+ base->variables.write[i].usages += 1;
return true;
}
}
@@ -7096,43 +7147,33 @@ bool GDScriptParser::_get_member_type(const DataType &p_base_type, const StringN
return false;
}
-GDScriptParser::DataType GDScriptParser::_reduce_identifier_type(const DataType *p_base_type, const StringName &p_identifier, int p_line) {
+GDScriptParser::DataType GDScriptParser::_reduce_identifier_type(const DataType *p_base_type, const StringName &p_identifier, int p_line, bool p_is_indexing) {
if (p_base_type && !p_base_type->has_type) {
return DataType();
}
DataType base_type;
+ DataType member_type;
- // Check classes in current file
- ClassNode *base = NULL;
if (!p_base_type) {
- base = current_class;
base_type.has_type = true;
base_type.is_constant = true;
base_type.kind = DataType::CLASS;
- base_type.class_type = base;
+ base_type.class_type = current_class;
} else {
base_type = DataType(*p_base_type);
- if (base_type.kind == DataType::CLASS) {
- base = base_type.class_type;
- }
- }
-
- DataType member_type;
-
- for (int i = 0; i < current_class->variables.size(); i++) {
- if (current_class->variables[i].identifier == p_identifier) {
- member_type = current_class->variables[i].data_type;
- current_class->variables.write[i].usages += 1;
- return member_type;
- }
}
if (_get_member_type(base_type, p_identifier, member_type)) {
return member_type;
}
+ if (p_is_indexing) {
+ // Don't look for globals since this is an indexed identifier
+ return DataType();
+ }
+
if (!p_base_type) {
// Possibly this is a global, check before failing
@@ -7190,7 +7231,7 @@ GDScriptParser::DataType GDScriptParser::_reduce_identifier_type(const DataType
Ref<GDScript> gds = scr;
if (gds.is_valid()) {
if (!gds->is_valid()) {
- _set_error("Class '" + p_identifier + "' could not be fully loaded (script error or cyclic inheritance).");
+ _set_error("Class '" + p_identifier + "' could not be fully loaded (script error or cyclic dependency).");
return DataType();
}
result.kind = DataType::GDSCRIPT;
@@ -7284,7 +7325,7 @@ void GDScriptParser::_check_class_level_types(ClassNode *p_class) {
DataType cont = _resolve_type(c.type, c.expression->line);
DataType expr = _resolve_type(c.expression->get_datatype(), c.expression->line);
- if (!_is_type_compatible(cont, expr)) {
+ if (check_types && !_is_type_compatible(cont, expr)) {
_set_error("Constant value type (" + expr.to_string() + ") is not compatible with declared type (" + cont.to_string() + ").",
c.expression->line);
return;
@@ -7328,7 +7369,7 @@ void GDScriptParser::_check_class_level_types(ClassNode *p_class) {
if (v.expression) {
DataType expr_type = _reduce_node_type(v.expression);
- if (!_is_type_compatible(v.data_type, expr_type)) {
+ if (check_types && !_is_type_compatible(v.data_type, expr_type)) {
// Try supertype test
if (_is_type_compatible(expr_type, v.data_type)) {
_mark_line_as_unsafe(v.line);
@@ -7790,7 +7831,7 @@ void GDScriptParser::_check_block_types(BlockNode *p_block) {
return;
}
- if (!lh_type.has_type) {
+ if (!lh_type.has_type && check_types) {
if (op->arguments[0]->type == Node::TYPE_OPERATOR) {
_mark_line_as_unsafe(op->line);
}
@@ -7812,7 +7853,7 @@ void GDScriptParser::_check_block_types(BlockNode *p_block) {
bool valid = false;
rh_type = _get_operation_type(oper, lh_type, arg_type, valid);
- if (!valid) {
+ if (check_types && !valid) {
_set_error("Invalid operand types ('" + lh_type.to_string() + "' and '" + arg_type.to_string() +
"') to assignment operator '" + Variant::get_operator_name(oper) + "'.",
op->line);
@@ -7835,7 +7876,7 @@ void GDScriptParser::_check_block_types(BlockNode *p_block) {
}
#endif // DEBUG_ENABLED
- if (!_is_type_compatible(lh_type, rh_type)) {
+ if (check_types && !_is_type_compatible(lh_type, rh_type)) {
// Try supertype test
if (_is_type_compatible(rh_type, lh_type)) {
_mark_line_as_unsafe(op->line);
@@ -7871,9 +7912,11 @@ void GDScriptParser::_check_block_types(BlockNode *p_block) {
#endif // DEBUG_ENABLED
}
}
+#ifdef DEBUG_ENABLED
if (!rh_type.has_type && (op->op != OperatorNode::OP_ASSIGN || lh_type.has_type || op->arguments[0]->type == Node::TYPE_OPERATOR)) {
_mark_line_as_unsafe(op->line);
}
+#endif // DEBUG_ENABLED
} break;
case OperatorNode::OP_CALL:
case OperatorNode::OP_PARENT_CALL: {
@@ -8125,6 +8168,7 @@ Error GDScriptParser::_parse(const String &p_base_path) {
}
#ifdef DEBUG_ENABLED
+
// Resolve warning ignores
Vector<Pair<int, String> > warning_skips = tokenizer->get_warning_skips();
bool warning_is_error = GLOBAL_GET("debug/gdscript/warnings/treat_warnings_as_errors").booleanize();
diff --git a/modules/gdscript/gdscript_parser.h b/modules/gdscript/gdscript_parser.h
index 8121fb7f85..d1ddf9aa12 100644
--- a/modules/gdscript/gdscript_parser.h
+++ b/modules/gdscript/gdscript_parser.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -95,6 +95,7 @@ public:
}
DataType() :
+ kind(UNRESOLVED),
has_type(false),
is_constant(false),
is_meta_type(false),
@@ -168,6 +169,7 @@ public:
MultiplayerAPI::RPCMode rpc_mode;
int usages;
};
+
struct Constant {
Node *expression;
DataType type;
@@ -607,7 +609,7 @@ private:
DataType _reduce_node_type(Node *p_node);
DataType _reduce_function_call_type(const OperatorNode *p_call);
- DataType _reduce_identifier_type(const DataType *p_base_type, const StringName &p_identifier, int p_line);
+ DataType _reduce_identifier_type(const DataType *p_base_type, const StringName &p_identifier, int p_line, bool p_is_indexing);
void _check_class_level_types(ClassNode *p_class);
void _check_class_blocks_types(ClassNode *p_class);
void _check_function_types(FunctionNode *p_function);
diff --git a/modules/gdscript/gdscript_tokenizer.cpp b/modules/gdscript/gdscript_tokenizer.cpp
index c37142b3c1..127a00a9f3 100644
--- a/modules/gdscript/gdscript_tokenizer.cpp
+++ b/modules/gdscript/gdscript_tokenizer.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/modules/gdscript/gdscript_tokenizer.h b/modules/gdscript/gdscript_tokenizer.h
index cc894fb101..e4315f7969 100644
--- a/modules/gdscript/gdscript_tokenizer.h
+++ b/modules/gdscript/gdscript_tokenizer.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -32,7 +32,7 @@
#define GDSCRIPT_TOKENIZER_H
#include "core/pair.h"
-#include "core/string_db.h"
+#include "core/string_name.h"
#include "core/ustring.h"
#include "core/variant.h"
#include "core/vmap.h"
diff --git a/modules/gdscript/register_types.cpp b/modules/gdscript/register_types.cpp
index 9c4dc0c926..b8a13ed91b 100644
--- a/modules/gdscript/register_types.cpp
+++ b/modules/gdscript/register_types.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -54,20 +54,74 @@ class EditorExportGDScript : public EditorExportPlugin {
public:
virtual void _export_file(const String &p_path, const String &p_type, const Set<String> &p_features) {
- if (!p_path.ends_with(".gd"))
+ int script_mode = EditorExportPreset::MODE_SCRIPT_COMPILED;
+ String script_key;
+
+ const Ref<EditorExportPreset> &preset = get_export_preset();
+
+ if (preset.is_valid()) {
+ script_mode = preset->get_script_export_mode();
+ script_key = preset->get_script_encryption_key().to_lower();
+ }
+
+ if (!p_path.ends_with(".gd") || script_mode == EditorExportPreset::MODE_SCRIPT_TEXT)
return;
Vector<uint8_t> file = FileAccess::get_file_as_array(p_path);
if (file.empty())
return;
+
String txt;
txt.parse_utf8((const char *)file.ptr(), file.size());
file = GDScriptTokenizerBuffer::parse_code_string(txt);
- if (file.empty())
- return;
-
- add_file(p_path.get_basename() + ".gdc", file, true);
+ if (!file.empty()) {
+
+ if (script_mode == EditorExportPreset::MODE_SCRIPT_ENCRYPTED) {
+
+ String tmp_path = EditorSettings::get_singleton()->get_cache_dir().plus_file("script.gde");
+ FileAccess *fa = FileAccess::open(tmp_path, FileAccess::WRITE);
+
+ Vector<uint8_t> key;
+ key.resize(32);
+ for (int i = 0; i < 32; i++) {
+ int v = 0;
+ if (i * 2 < script_key.length()) {
+ CharType ct = script_key[i * 2];
+ if (ct >= '0' && ct <= '9')
+ ct = ct - '0';
+ else if (ct >= 'a' && ct <= 'f')
+ ct = 10 + ct - 'a';
+ v |= ct << 4;
+ }
+
+ if (i * 2 + 1 < script_key.length()) {
+ CharType ct = script_key[i * 2 + 1];
+ if (ct >= '0' && ct <= '9')
+ ct = ct - '0';
+ else if (ct >= 'a' && ct <= 'f')
+ ct = 10 + ct - 'a';
+ v |= ct;
+ }
+ key.write[i] = v;
+ }
+ FileAccessEncrypted *fae = memnew(FileAccessEncrypted);
+ Error err = fae->open_and_parse(fa, key, FileAccessEncrypted::MODE_WRITE_AES256);
+
+ if (err == OK) {
+ fae->store_buffer(file.ptr(), file.size());
+ }
+
+ memdelete(fae);
+
+ file = FileAccess::get_file_as_array(tmp_path);
+ add_file(p_path.get_basename() + ".gde", file, true);
+
+ } else {
+
+ add_file(p_path.get_basename() + ".gdc", file, true);
+ }
+ }
}
};
@@ -107,13 +161,9 @@ void unregister_gdscript_types() {
if (script_language_gd)
memdelete(script_language_gd);
- if (resource_loader_gd.is_valid()) {
- ResourceLoader::remove_resource_format_loader(resource_loader_gd);
- resource_loader_gd.unref();
- }
+ ResourceLoader::remove_resource_format_loader(resource_loader_gd);
+ resource_loader_gd.unref();
- if (resource_saver_gd.is_valid()) {
- ResourceSaver::remove_resource_format_saver(resource_saver_gd);
- resource_saver_gd.unref();
- }
+ ResourceSaver::remove_resource_format_saver(resource_saver_gd);
+ resource_saver_gd.unref();
}
diff --git a/modules/gdscript/register_types.h b/modules/gdscript/register_types.h
index 2b88a67c7e..0f01a4cdab 100644
--- a/modules/gdscript/register_types.h
+++ b/modules/gdscript/register_types.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */