diff options
Diffstat (limited to 'modules/gdscript')
-rw-r--r-- | modules/gdscript/SCsub | 5 | ||||
-rw-r--r-- | modules/gdscript/doc_classes/GDScript.xml | 3 | ||||
-rw-r--r-- | modules/gdscript/doc_classes/GDScriptFunctionState.xml | 2 | ||||
-rw-r--r-- | modules/gdscript/doc_classes/GDScriptNativeClass.xml | 2 | ||||
-rw-r--r-- | modules/gdscript/gdscript.cpp | 7 | ||||
-rw-r--r-- | modules/gdscript/gdscript.h | 9 | ||||
-rw-r--r-- | modules/gdscript/gdscript_compiler.cpp | 43 | ||||
-rw-r--r-- | modules/gdscript/gdscript_compiler.h | 5 | ||||
-rw-r--r-- | modules/gdscript/gdscript_editor.cpp | 25 | ||||
-rw-r--r-- | modules/gdscript/gdscript_function.cpp | 13 | ||||
-rw-r--r-- | modules/gdscript/gdscript_function.h | 5 | ||||
-rw-r--r-- | modules/gdscript/gdscript_functions.cpp | 23 | ||||
-rw-r--r-- | modules/gdscript/gdscript_functions.h | 5 | ||||
-rw-r--r-- | modules/gdscript/gdscript_parser.cpp | 142 | ||||
-rw-r--r-- | modules/gdscript/gdscript_parser.h | 5 | ||||
-rw-r--r-- | modules/gdscript/gdscript_tokenizer.cpp | 5 | ||||
-rw-r--r-- | modules/gdscript/gdscript_tokenizer.h | 5 | ||||
-rw-r--r-- | modules/gdscript/register_types.cpp | 49 | ||||
-rw-r--r-- | modules/gdscript/register_types.h | 5 |
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(); |