summaryrefslogtreecommitdiff
path: root/modules/gdscript
diff options
context:
space:
mode:
Diffstat (limited to 'modules/gdscript')
-rw-r--r--modules/gdscript/SCsub5
-rw-r--r--modules/gdscript/doc_classes/GDScript.xml3
-rw-r--r--modules/gdscript/doc_classes/GDScriptFunctionState.xml2
-rw-r--r--modules/gdscript/doc_classes/GDScriptNativeClass.xml2
-rw-r--r--modules/gdscript/gdscript.cpp7
-rw-r--r--modules/gdscript/gdscript.h9
-rw-r--r--modules/gdscript/gdscript_compiler.cpp43
-rw-r--r--modules/gdscript/gdscript_compiler.h5
-rw-r--r--modules/gdscript/gdscript_editor.cpp25
-rw-r--r--modules/gdscript/gdscript_function.cpp13
-rw-r--r--modules/gdscript/gdscript_function.h5
-rw-r--r--modules/gdscript/gdscript_functions.cpp23
-rw-r--r--modules/gdscript/gdscript_functions.h5
-rw-r--r--modules/gdscript/gdscript_parser.cpp142
-rw-r--r--modules/gdscript/gdscript_parser.h5
-rw-r--r--modules/gdscript/gdscript_tokenizer.cpp5
-rw-r--r--modules/gdscript/gdscript_tokenizer.h5
-rw-r--r--modules/gdscript/register_types.cpp49
-rw-r--r--modules/gdscript/register_types.h5
19 files changed, 243 insertions, 115 deletions
diff --git a/modules/gdscript/SCsub b/modules/gdscript/SCsub
index 0882406761..13870170a5 100644
--- a/modules/gdscript/SCsub
+++ b/modules/gdscript/SCsub
@@ -1,7 +1,10 @@
#!/usr/bin/env python
Import('env')
+Import('env_modules')
-env.add_source_files(env.modules_sources, "*.cpp")
+env_gdscript = env_modules.Clone()
+
+env_gdscript.add_source_files(env.modules_sources, "*.cpp")
Export('env')
diff --git a/modules/gdscript/doc_classes/GDScript.xml b/modules/gdscript/doc_classes/GDScript.xml
index cc617c5c67..0dc69c3688 100644
--- a/modules/gdscript/doc_classes/GDScript.xml
+++ b/modules/gdscript/doc_classes/GDScript.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
-<class name="GDScript" inherits="Script" category="Core" version="3.0-beta">
+<class name="GDScript" inherits="Script" category="Core" version="3.1-dev">
<brief_description>
A script implemented in the GDScript programming language.
</brief_description>
@@ -8,6 +8,7 @@
[method new] creates a new instance of the script. [method Object.set_script] extends an existing object, if that object's class matches one of the script's base classes.
</description>
<tutorials>
+ http://docs.godotengine.org/en/3.0/getting_started/scripting/gdscript/index.html
</tutorials>
<demos>
</demos>
diff --git a/modules/gdscript/doc_classes/GDScriptFunctionState.xml b/modules/gdscript/doc_classes/GDScriptFunctionState.xml
index 465a4f438b..254d968e1b 100644
--- a/modules/gdscript/doc_classes/GDScriptFunctionState.xml
+++ b/modules/gdscript/doc_classes/GDScriptFunctionState.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
-<class name="GDScriptFunctionState" inherits="Reference" category="Core" version="3.0-beta">
+<class name="GDScriptFunctionState" inherits="Reference" category="Core" version="3.1-dev">
<brief_description>
State of a function call after yielding.
</brief_description>
diff --git a/modules/gdscript/doc_classes/GDScriptNativeClass.xml b/modules/gdscript/doc_classes/GDScriptNativeClass.xml
index 948254e0ad..1abcc4762f 100644
--- a/modules/gdscript/doc_classes/GDScriptNativeClass.xml
+++ b/modules/gdscript/doc_classes/GDScriptNativeClass.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
-<class name="GDScriptNativeClass" inherits="Reference" category="Core" version="3.0-beta">
+<class name="GDScriptNativeClass" inherits="Reference" category="Core" version="3.1-dev">
<brief_description>
</brief_description>
<description>
diff --git a/modules/gdscript/gdscript.cpp b/modules/gdscript/gdscript.cpp
index b75f670906..4e3ee4d22c 100644
--- a/modules/gdscript/gdscript.cpp
+++ b/modules/gdscript/gdscript.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2018 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 */
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#include "gdscript.h"
#include "engine.h"
@@ -704,7 +705,7 @@ bool GDScript::_set(const StringName &p_name, const Variant &p_value) {
void GDScript::_get_property_list(List<PropertyInfo> *p_properties) const {
- p_properties->push_back(PropertyInfo(Variant::STRING, "script/source", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
+ p_properties->push_back(PropertyInfo(Variant::STRING, "script/source", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL));
}
void GDScript::_bind_methods() {
diff --git a/modules/gdscript/gdscript.h b/modules/gdscript/gdscript.h
index 6e5d59ad0e..9566e3b32e 100644
--- a/modules/gdscript/gdscript.h
+++ b/modules/gdscript/gdscript.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2018 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 */
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#ifndef GDSCRIPT_H
#define GDSCRIPT_H
@@ -348,7 +349,9 @@ public:
csi.resize(_debug_call_stack_pos);
for (int i = 0; i < _debug_call_stack_pos; i++) {
csi[_debug_call_stack_pos - i - 1].line = _call_stack[i].line ? *_call_stack[i].line : 0;
- csi[_debug_call_stack_pos - i - 1].script = Ref<GDScript>(_call_stack[i].function->get_script());
+ if (_call_stack[i].function)
+ csi[_debug_call_stack_pos - i - 1].func = _call_stack[i].function->get_name();
+ csi[_debug_call_stack_pos - i - 1].file = _call_stack[i].function->get_script()->get_path();
}
return csi;
}
diff --git a/modules/gdscript/gdscript_compiler.cpp b/modules/gdscript/gdscript_compiler.cpp
index f9385d7a11..1649fb52f2 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-2017 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2018 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 */
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#include "gdscript_compiler.h"
#include "gdscript.h"
@@ -36,6 +37,9 @@ bool GDScriptCompiler::_is_class_member_property(CodeGen &codegen, const StringN
if (!codegen.function_node || codegen.function_node->_static)
return false;
+ if (codegen.stack_identifiers.has(p_name))
+ return false; //shadowed
+
return _is_class_member_property(codegen.script, p_name);
}
@@ -183,6 +187,14 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser::
StringName identifier = in->name;
+ // TRY STACK!
+ if (!p_initializer && codegen.stack_identifiers.has(identifier)) {
+
+ int pos = codegen.stack_identifiers[identifier];
+ return pos | (GDScriptFunction::ADDR_TYPE_STACK_VARIABLE << GDScriptFunction::ADDR_BITS);
+ }
+
+ // TRY CLASS MEMBER
if (_is_class_member_property(codegen, identifier)) {
//get property
codegen.opcodes.push_back(GDScriptFunction::OPCODE_GET_MEMBER); // perform operator
@@ -193,12 +205,6 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser::
return dst_addr;
}
- // TRY STACK!
- if (!p_initializer && codegen.stack_identifiers.has(identifier)) {
-
- int pos = codegen.stack_identifiers[identifier];
- return pos | (GDScriptFunction::ADDR_TYPE_STACK_VARIABLE << GDScriptFunction::ADDR_BITS);
- }
//TRY MEMBERS!
if (!codegen.function_node || !codegen.function_node->_static) {
@@ -1335,10 +1341,12 @@ Error GDScriptCompiler::_parse_block(CodeGen &codegen, const GDScriptParser::Blo
const GDScriptParser::LocalVarNode *lv = static_cast<const GDScriptParser::LocalVarNode *>(s);
- if (_is_class_member_property(codegen, lv->name)) {
- _set_error("Name for local variable '" + String(lv->name) + "' can't shadow class property of the same name.", lv);
- return ERR_ALREADY_EXISTS;
- }
+ // since we are using properties now for most class access, allow shadowing of class members to make user's life easier.
+ //
+ //if (_is_class_member_property(codegen, lv->name)) {
+ // _set_error("Name for local variable '" + String(lv->name) + "' can't shadow class property of the same name.", lv);
+ // return ERR_ALREADY_EXISTS;
+ //}
codegen.add_stack_identifier(lv->name, p_stack_level++);
codegen.alloc_stack(p_stack_level);
@@ -1375,10 +1383,13 @@ Error GDScriptCompiler::_parse_function(GDScript *p_script, const GDScriptParser
if (p_func) {
for (int i = 0; i < p_func->arguments.size(); i++) {
- if (_is_class_member_property(p_script, p_func->arguments[i])) {
- _set_error("Name for argument '" + String(p_func->arguments[i]) + "' can't shadow class property of the same name.", p_func);
- return ERR_ALREADY_EXISTS;
- }
+ // since we are using properties now for most class access, allow shadowing of class members to make user's life easier.
+ //
+ //if (_is_class_member_property(p_script, p_func->arguments[i])) {
+ // _set_error("Name for argument '" + String(p_func->arguments[i]) + "' can't shadow class property of the same name.", p_func);
+ // return ERR_ALREADY_EXISTS;
+ //}
+
codegen.add_stack_identifier(p_func->arguments[i], i);
#ifdef TOOLS_ENABLED
argnames.push_back(p_func->arguments[i]);
diff --git a/modules/gdscript/gdscript_compiler.h b/modules/gdscript/gdscript_compiler.h
index 6e0457ba30..62aafdbe01 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-2017 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2018 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 */
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#ifndef GDSCRIPT_COMPILER_H
#define GDSCRIPT_COMPILER_H
diff --git a/modules/gdscript/gdscript_editor.cpp b/modules/gdscript/gdscript_editor.cpp
index adf6780278..505562324f 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-2017 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2018 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 */
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#include "gdscript.h"
#include "core/engine.h"
@@ -368,8 +369,8 @@ void GDScriptLanguage::get_public_functions(List<MethodInfo> *p_functions) const
mi.name = "yield";
mi.arguments.push_back(PropertyInfo(Variant::OBJECT, "object"));
mi.arguments.push_back(PropertyInfo(Variant::STRING, "signal"));
- mi.default_arguments.push_back(Variant::NIL);
- mi.default_arguments.push_back(Variant::STRING);
+ mi.default_arguments.push_back(Variant());
+ mi.default_arguments.push_back(String());
mi.return_val = PropertyInfo(Variant::OBJECT, "", PROPERTY_HINT_RESOURCE_TYPE, "GDScriptFunctionState");
p_functions->push_back(mi);
}
@@ -490,8 +491,8 @@ static Ref<Reference> _get_parent_class(GDScriptCompletionContext &context) {
path = context.base_path.plus_file(path);
}
- if (ScriptCodeCompletionCache::get_sigleton())
- script = ScriptCodeCompletionCache::get_sigleton()->get_cached_resource(path);
+ if (ScriptCodeCompletionCache::get_singleton())
+ script = ScriptCodeCompletionCache::get_singleton()->get_cached_resource(path);
else
script = ResourceLoader::load(path);
@@ -764,8 +765,8 @@ static bool _guess_expression_type(GDScriptCompletionContext &context, const GDS
//print_line("is a script");
Ref<Script> scr;
- if (ScriptCodeCompletionCache::get_sigleton())
- scr = ScriptCodeCompletionCache::get_sigleton()->get_cached_resource(script);
+ if (ScriptCodeCompletionCache::get_singleton())
+ scr = ScriptCodeCompletionCache::get_singleton()->get_cached_resource(script);
else
scr = ResourceLoader::load(script);
@@ -1300,8 +1301,8 @@ static bool _guess_identifier_type(GDScriptCompletionContext &context, int p_lin
//print_line("is a script");
Ref<Script> scr;
- if (ScriptCodeCompletionCache::get_sigleton())
- scr = ScriptCodeCompletionCache::get_sigleton()->get_cached_resource(script);
+ if (ScriptCodeCompletionCache::get_singleton())
+ scr = ScriptCodeCompletionCache::get_singleton()->get_cached_resource(script);
else
scr = ResourceLoader::load(script);
@@ -2449,8 +2450,10 @@ Error GDScriptLanguage::complete_code(const String &p_code, const String &p_base
} break;
case GDScriptParser::COMPLETION_RESOURCE_PATH: {
- if (EditorSettings::get_singleton()->get("text_editor/completion/complete_file_paths"))
+ if (EditorSettings::get_singleton()->get("text_editor/completion/complete_file_paths")) {
get_directory_contents(EditorFileSystem::get_singleton()->get_filesystem(), options);
+ r_forced = true;
+ }
} break;
case GDScriptParser::COMPLETION_ASSIGN: {
#if defined(DEBUG_METHODS_ENABLED) && defined(TOOLS_ENABLED)
diff --git a/modules/gdscript/gdscript_function.cpp b/modules/gdscript/gdscript_function.cpp
index d2ce318f82..a2f449909f 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-2017 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2018 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 */
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#include "gdscript_function.h"
#include "gdscript.h"
@@ -515,7 +516,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
} else {
v = "of type '" + _get_var_type(index) + "'";
}
- err_text = "Invalid set index " + v + " (on base: '" + _get_var_type(dst) + "') with value of type '"+_get_var_type(value)+"'";
+ err_text = "Invalid set index " + v + " (on base: '" + _get_var_type(dst) + "') with value of type '" + _get_var_type(value) + "'";
OPCODE_BREAK;
}
#endif
@@ -574,7 +575,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
#ifdef DEBUG_ENABLED
if (!valid) {
String err_type;
- err_text = "Invalid set index '" + String(*index) + "' (on base: '" + _get_var_type(dst) + "') with value of type '"+_get_var_type(value)+"'.";
+ err_text = "Invalid set index '" + String(*index) + "' (on base: '" + _get_var_type(dst) + "') with value of type '" + _get_var_type(value) + "'.";
OPCODE_BREAK;
}
#endif
@@ -605,7 +606,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
#ifdef DEBUG_ENABLED
if (!valid) {
if (src->has_method(*index)) {
- err_text = "Invalid get index '" + index->operator String() + "' (on base: '" + _get_var_type(src) + "'). Did you mean '." + index->operator String() + "()' ?";
+ err_text = "Invalid get index '" + index->operator String() + "' (on base: '" + _get_var_type(src) + "'). Did you mean '." + index->operator String() + "()' or funcref(obj, \"" + index->operator String() + "\") ?";
} else {
err_text = "Invalid get index '" + index->operator String() + "' (on base: '" + _get_var_type(src) + "').";
}
@@ -1257,6 +1258,8 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
exit_ok = true;
OPCODE_BREAK;
}
+
+// Enable for debugging
#if 0
default: {
diff --git a/modules/gdscript/gdscript_function.h b/modules/gdscript/gdscript_function.h
index 03fd5d52dc..9310444c7a 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-2017 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2018 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 */
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#ifndef GDSCRIPT_FUNCTION_H
#define GDSCRIPT_FUNCTION_H
diff --git a/modules/gdscript/gdscript_functions.cpp b/modules/gdscript/gdscript_functions.cpp
index ca0a9582a7..278585cb01 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-2017 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2018 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 */
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#include "gdscript_functions.h"
#include "class_db.h"
@@ -357,13 +358,16 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_
r_ret = Math::dectime((double)*p_args[0], (double)*p_args[1], (double)*p_args[2]);
} break;
case MATH_RANDOMIZE: {
+ VALIDATE_ARG_COUNT(0);
Math::randomize();
r_ret = Variant();
} break;
case MATH_RAND: {
+ VALIDATE_ARG_COUNT(0);
r_ret = Math::rand();
} break;
case MATH_RANDF: {
+ VALIDATE_ARG_COUNT(0);
r_ret = Math::randf();
} break;
case MATH_RANDOM: {
@@ -592,7 +596,13 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_
r_ret = String(result);
} break;
case TEXT_STR: {
+ if (p_arg_count < 1) {
+ r_error.error = Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
+ r_error.argument = 1;
+ r_ret = Variant();
+ return;
+ }
String str;
for (int i = 0; i < p_arg_count; i++) {
@@ -1179,6 +1189,7 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_
} break;
case PRINT_STACK: {
+ VALIDATE_ARG_COUNT(0);
ScriptLanguage *script = GDScriptLanguage::get_singleton();
for (int i = 0; i < script->debug_get_stack_level_count(); i++) {
@@ -1482,7 +1493,7 @@ MethodInfo GDScriptFunctions::get_info(Function p_func) {
return mi;
} break;
case MATH_INVERSE_LERP: {
- MethodInfo mi("inverse_lerp", PropertyInfo(Variant::REAL, "from"), PropertyInfo(Variant::REAL, "to"), PropertyInfo(Variant::REAL, "value"));
+ MethodInfo mi("inverse_lerp", PropertyInfo(Variant::REAL, "from"), PropertyInfo(Variant::REAL, "to"), PropertyInfo(Variant::REAL, "weight"));
mi.return_val.type = Variant::REAL;
return mi;
} break;
@@ -1578,12 +1589,12 @@ MethodInfo GDScriptFunctions::get_info(Function p_func) {
return mi;
} break;
case LOGIC_CLAMP: {
- MethodInfo mi("clamp", PropertyInfo(Variant::REAL, "val"), PropertyInfo(Variant::REAL, "min"), PropertyInfo(Variant::REAL, "max"));
+ MethodInfo mi("clamp", PropertyInfo(Variant::REAL, "value"), PropertyInfo(Variant::REAL, "min"), PropertyInfo(Variant::REAL, "max"));
mi.return_val.type = Variant::REAL;
return mi;
} break;
case LOGIC_NEAREST_PO2: {
- MethodInfo mi("nearest_po2", PropertyInfo(Variant::INT, "val"));
+ MethodInfo mi("nearest_po2", PropertyInfo(Variant::INT, "value"));
mi.return_val.type = Variant::INT;
return mi;
} break;
@@ -1759,12 +1770,14 @@ MethodInfo GDScriptFunctions::get_info(Function p_func) {
case COLOR8: {
MethodInfo mi("Color8", PropertyInfo(Variant::INT, "r8"), PropertyInfo(Variant::INT, "g8"), PropertyInfo(Variant::INT, "b8"), PropertyInfo(Variant::INT, "a8"));
+ mi.default_arguments.push_back(255);
mi.return_val.type = Variant::COLOR;
return mi;
} break;
case COLORN: {
MethodInfo mi("ColorN", PropertyInfo(Variant::STRING, "name"), PropertyInfo(Variant::REAL, "alpha"));
+ mi.default_arguments.push_back(1.0f);
mi.return_val.type = Variant::COLOR;
return mi;
} break;
diff --git a/modules/gdscript/gdscript_functions.h b/modules/gdscript/gdscript_functions.h
index d1c5815cec..1d54006084 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-2017 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2018 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 */
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#ifndef GDSCRIPT_FUNCTIONS_H
#define GDSCRIPT_FUNCTIONS_H
diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp
index e48b03968b..cd752a786c 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-2017 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2018 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 */
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#include "gdscript_parser.h"
#include "gdscript.h"
@@ -94,8 +95,6 @@ bool GDScriptParser::_enter_indent_block(BlockNode *p_block) {
int indent = tokenizer->get_token_line_indent();
int current = tab_level.back()->get();
if (indent <= current) {
- print_line("current: " + itos(current) + " indent: " + itos(indent));
- print_line("less than current");
return false;
}
@@ -457,9 +456,9 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
if (!validating) {
//this can be too slow for just validating code
- if (for_completion && ScriptCodeCompletionCache::get_sigleton()) {
- res = ScriptCodeCompletionCache::get_sigleton()->get_cached_resource(path);
- } else {
+ if (for_completion && ScriptCodeCompletionCache::get_singleton() && FileAccess::exists(path)) {
+ res = ScriptCodeCompletionCache::get_singleton()->get_cached_resource(path);
+ } else if (!for_completion || FileAccess::exists(path)) {
res = ResourceLoader::load(path);
}
if (!res.is_valid()) {
@@ -577,18 +576,47 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
if (identifier == StringName()) {
- _set_error("Built-in type constant expected after '.'");
+ _set_error("Built-in type constant or static function expected after '.'");
return NULL;
}
if (!Variant::has_numeric_constant(bi_type, identifier)) {
- _set_error("Static constant '" + identifier.operator String() + "' not present in built-in type " + Variant::get_type_name(bi_type) + ".");
- return NULL;
- }
+ if (tokenizer->get_token() == GDScriptTokenizer::TK_PARENTHESIS_OPEN &&
+ Variant::is_method_const(bi_type, identifier) &&
+ Variant::get_method_return_type(bi_type, identifier) == bi_type) {
+
+ tokenizer->advance();
+
+ OperatorNode *construct = alloc_node<OperatorNode>();
+ construct->op = OperatorNode::OP_CALL;
+
+ TypeNode *tn = alloc_node<TypeNode>();
+ tn->vtype = bi_type;
+ construct->arguments.push_back(tn);
+
+ OperatorNode *op = alloc_node<OperatorNode>();
+ op->op = OperatorNode::OP_CALL;
+ op->arguments.push_back(construct);
+
+ IdentifierNode *id = alloc_node<IdentifierNode>();
+ id->name = identifier;
+ op->arguments.push_back(id);
+
+ if (!_parse_arguments(op, op->arguments, p_static, true))
+ return NULL;
+
+ expr = op;
+ } else {
+
+ _set_error("Static constant '" + identifier.operator String() + "' not present in built-in type " + Variant::get_type_name(bi_type) + ".");
+ return NULL;
+ }
+ } else {
- ConstantNode *cn = alloc_node<ConstantNode>();
- cn->value = Variant::get_numeric_constant_value(bi_type, identifier);
- expr = cn;
+ ConstantNode *cn = alloc_node<ConstantNode>();
+ cn->value = Variant::get_numeric_constant_value(bi_type, identifier);
+ expr = cn;
+ }
} else if (tokenizer->get_token(1) == GDScriptTokenizer::TK_PARENTHESIS_OPEN && tokenizer->is_token_literal()) {
// We check with is_token_literal, as this allows us to use match/sync/etc. as a name
@@ -597,12 +625,36 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
OperatorNode *op = alloc_node<OperatorNode>();
op->op = OperatorNode::OP_CALL;
+ //Do a quick Array and Dictionary Check. Replace if either require no arguments.
+ bool replaced = false;
+
if (tokenizer->get_token() == GDScriptTokenizer::TK_BUILT_IN_TYPE) {
+ Variant::Type ct = tokenizer->get_token_type();
+ if (p_parsing_constant == false) {
+ if (ct == Variant::ARRAY) {
+ if (tokenizer->get_token(2) == GDScriptTokenizer::TK_PARENTHESIS_CLOSE) {
+ ArrayNode *arr = alloc_node<ArrayNode>();
+ expr = arr;
+ replaced = true;
+ tokenizer->advance(3);
+ }
+ }
+ if (ct == Variant::DICTIONARY) {
+ if (tokenizer->get_token(2) == GDScriptTokenizer::TK_PARENTHESIS_CLOSE) {
+ DictionaryNode *dict = alloc_node<DictionaryNode>();
+ expr = dict;
+ replaced = true;
+ tokenizer->advance(3);
+ }
+ }
+ }
- TypeNode *tn = alloc_node<TypeNode>();
- tn->vtype = tokenizer->get_token_type();
- op->arguments.push_back(tn);
- tokenizer->advance(2);
+ if (!replaced) {
+ TypeNode *tn = alloc_node<TypeNode>();
+ tn->vtype = tokenizer->get_token_type();
+ op->arguments.push_back(tn);
+ tokenizer->advance(2);
+ }
} else if (tokenizer->get_token() == GDScriptTokenizer::TK_BUILT_IN_FUNC) {
BuiltInFunctionNode *bn = alloc_node<BuiltInFunctionNode>();
@@ -628,11 +680,11 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
_make_completable_call(0);
completion_node = op;
}
- if (!_parse_arguments(op, op->arguments, p_static, true))
- return NULL;
-
- expr = op;
-
+ if (!replaced) {
+ if (!_parse_arguments(op, op->arguments, p_static, true))
+ return NULL;
+ expr = op;
+ }
} else if (tokenizer->is_token_literal(0, true)) {
// We check with is_token_literal, as this allows us to use match/sync/etc. as a name
//identifier (reference)
@@ -1140,6 +1192,7 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
bool unary = false;
bool ternary = false;
bool error = false;
+ bool right_to_left = false;
switch (expression[i].op) {
@@ -1194,11 +1247,13 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
case OperatorNode::OP_TERNARY_IF:
priority = 14;
ternary = true;
+ right_to_left = true;
break;
case OperatorNode::OP_TERNARY_ELSE:
priority = 14;
error = true;
- break; // Errors out when found without IF (since IF would consume it)
+ // Rigth-to-left should be false in this case, otherwise it would always error.
+ break;
case OperatorNode::OP_ASSIGN: priority = 15; break;
case OperatorNode::OP_ASSIGN_ADD: priority = 15; break;
@@ -1218,13 +1273,13 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
}
}
- if (priority < min_priority) {
+ if (priority < min_priority || (right_to_left && priority == min_priority)) {
+ // < is used for left to right (default)
+ // <= is used for right to left
if (error) {
_set_error("Unexpected operator");
return NULL;
}
- // < is used for left to right (default)
- // <= is used for right to left
next_op = i;
min_priority = priority;
is_unary = unary;
@@ -1490,11 +1545,11 @@ GDScriptParser::Node *GDScriptParser::_reduce_expression(Node *p_node, bool p_to
String errwhere;
if (op->arguments[0]->type == Node::TYPE_TYPE) {
TypeNode *tn = static_cast<TypeNode *>(op->arguments[0]);
- errwhere = "'" + Variant::get_type_name(tn->vtype) + "'' constructor";
+ errwhere = "'" + Variant::get_type_name(tn->vtype) + "' constructor";
} else {
GDScriptFunctions::Function func = static_cast<BuiltInFunctionNode *>(op->arguments[0])->function;
- errwhere = String("'") + GDScriptFunctions::get_func_name(func) + "'' intrinsic function";
+ errwhere = String("'") + GDScriptFunctions::get_func_name(func) + "' intrinsic function";
}
switch (ce.error) {
@@ -3389,6 +3444,10 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
_set_error("Can't export null type.");
return;
}
+ if (type == Variant::OBJECT) {
+ _set_error("Can't export raw object type.");
+ return;
+ }
current_export.type = type;
current_export.usage |= PROPERTY_USAGE_SCRIPT_VARIABLE;
tokenizer->advance();
@@ -4326,8 +4385,6 @@ Error GDScriptParser::_parse(const String &p_base_path) {
base_path = p_base_path;
- clear();
-
//assume class
ClassNode *main_class = alloc_node<ClassNode>();
main_class->initializer = alloc_node<BlockNode>();
@@ -4352,17 +4409,7 @@ Error GDScriptParser::_parse(const String &p_base_path) {
Error GDScriptParser::parse_bytecode(const Vector<uint8_t> &p_bytecode, const String &p_base_path, const String &p_self_path) {
- for_completion = false;
- validating = false;
- completion_type = COMPLETION_NONE;
- completion_node = NULL;
- completion_class = NULL;
- completion_function = NULL;
- completion_block = NULL;
- completion_found = false;
- current_block = NULL;
- current_class = NULL;
- current_function = NULL;
+ clear();
self_path = p_self_path;
GDScriptTokenizerBuffer *tb = memnew(GDScriptTokenizerBuffer);
@@ -4376,16 +4423,7 @@ Error GDScriptParser::parse_bytecode(const Vector<uint8_t> &p_bytecode, const St
Error GDScriptParser::parse(const String &p_code, const String &p_base_path, bool p_just_validate, const String &p_self_path, bool p_for_completion) {
- completion_type = COMPLETION_NONE;
- completion_node = NULL;
- completion_class = NULL;
- completion_function = NULL;
- completion_block = NULL;
- completion_found = false;
- current_block = NULL;
- current_class = NULL;
-
- current_function = NULL;
+ clear();
self_path = p_self_path;
GDScriptTokenizerText *tt = memnew(GDScriptTokenizerText);
diff --git a/modules/gdscript/gdscript_parser.h b/modules/gdscript/gdscript_parser.h
index 3c9c5ea02c..485ba1263d 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-2017 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2018 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 */
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#ifndef GDSCRIPT_PARSER_H
#define GDSCRIPT_PARSER_H
diff --git a/modules/gdscript/gdscript_tokenizer.cpp b/modules/gdscript/gdscript_tokenizer.cpp
index e3a0af8ee6..6a844cd651 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-2017 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2018 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 */
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#include "gdscript_tokenizer.h"
#include "gdscript_functions.h"
diff --git a/modules/gdscript/gdscript_tokenizer.h b/modules/gdscript/gdscript_tokenizer.h
index d19367177b..b020c85199 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-2017 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2018 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 */
@@ -27,6 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#ifndef GDSCRIPT_TOKENIZER_H
#define GDSCRIPT_TOKENIZER_H
diff --git a/modules/gdscript/register_types.cpp b/modules/gdscript/register_types.cpp
index 1e007ddb0f..95efcda80f 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-2017 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2018 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 */
@@ -27,9 +27,11 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#include "register_types.h"
#include "gdscript.h"
+#include "gdscript_tokenizer.h"
#include "io/file_access_encrypted.h"
#include "io/resource_loader.h"
#include "os/file_access.h"
@@ -38,6 +40,45 @@ GDScriptLanguage *script_language_gd = NULL;
ResourceFormatLoaderGDScript *resource_loader_gd = NULL;
ResourceFormatSaverGDScript *resource_saver_gd = NULL;
+#ifdef TOOLS_ENABLED
+
+#include "editor/editor_export.h"
+#include "editor/editor_node.h"
+#include "editor/editor_settings.h"
+
+class EditorExportGDScript : public EditorExportPlugin {
+
+ GDCLASS(EditorExportGDScript, 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"))
+ 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);
+ }
+};
+
+static void _editor_init() {
+
+ Ref<EditorExportGDScript> gd_export;
+ gd_export.instance();
+ EditorExport::get_singleton()->add_export_plugin(gd_export);
+}
+
+#endif
+
void register_gdscript_types() {
ClassDB::register_class<GDScript>();
@@ -49,6 +90,10 @@ void register_gdscript_types() {
ResourceLoader::add_resource_format_loader(resource_loader_gd);
resource_saver_gd = memnew(ResourceFormatSaverGDScript);
ResourceSaver::add_resource_format_saver(resource_saver_gd);
+
+#ifdef TOOLS_ENABLED
+ EditorNode::add_init_callback(_editor_init);
+#endif
}
void unregister_gdscript_types() {
diff --git a/modules/gdscript/register_types.h b/modules/gdscript/register_types.h
index a674877f37..2b88a67c7e 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-2017 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2018 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 */
@@ -27,5 +27,6 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
void register_gdscript_types();
void unregister_gdscript_types();