summaryrefslogtreecommitdiff
path: root/modules/gdscript
diff options
context:
space:
mode:
Diffstat (limited to 'modules/gdscript')
-rw-r--r--modules/gdscript/gdscript.cpp2
-rw-r--r--modules/gdscript/gdscript_editor.cpp30
-rw-r--r--modules/gdscript/gdscript_function.h13
-rw-r--r--modules/gdscript/gdscript_parser.cpp25
-rw-r--r--modules/gdscript/gdscript_parser.h2
-rw-r--r--modules/gdscript/gdscript_tokenizer.h2
6 files changed, 59 insertions, 15 deletions
diff --git a/modules/gdscript/gdscript.cpp b/modules/gdscript/gdscript.cpp
index 6d85eb3c90..f29432666e 100644
--- a/modules/gdscript/gdscript.cpp
+++ b/modules/gdscript/gdscript.cpp
@@ -483,7 +483,7 @@ bool GDScript::_update_exports() {
placeholder_fallback_enabled = true;
return false;
}
- } else if (!valid || placeholder_fallback_enabled) {
+ } else if (placeholder_fallback_enabled) {
return false;
}
diff --git a/modules/gdscript/gdscript_editor.cpp b/modules/gdscript/gdscript_editor.cpp
index 08ad101967..af770ac533 100644
--- a/modules/gdscript/gdscript_editor.cpp
+++ b/modules/gdscript/gdscript_editor.cpp
@@ -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;
@@ -1355,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) {
@@ -1544,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;
@@ -2309,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;
diff --git a/modules/gdscript/gdscript_function.h b/modules/gdscript/gdscript_function.h
index f4058664ff..cefc28d77f 100644
--- a/modules/gdscript/gdscript_function.h
+++ b/modules/gdscript/gdscript_function.h
@@ -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;
@@ -113,6 +116,8 @@ struct GDScriptDataType {
PropertyInfo info;
if (has_type) {
switch (kind) {
+ case UNINITIALIZED:
+ break;
case BUILTIN: {
info.type = builtin_type;
} break;
@@ -134,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_parser.cpp b/modules/gdscript/gdscript_parser.cpp
index 7334e8a8cc..b53d37226c 100644
--- a/modules/gdscript/gdscript_parser.cpp
+++ b/modules/gdscript/gdscript_parser.cpp
@@ -4557,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;
@@ -4724,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) {
@@ -5598,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;
@@ -6799,7 +6822,7 @@ GDScriptParser::DataType GDScriptParser::_reduce_function_call_type(const Operat
return_type = original_type;
return_type.is_meta_type = false;
- valid = true; // There's always an initializer, we can asume this is true
+ valid = true; // There's always an initializer, we can assume this is true
}
if (!valid) {
diff --git a/modules/gdscript/gdscript_parser.h b/modules/gdscript/gdscript_parser.h
index b4a705c9e7..d1ddf9aa12 100644
--- a/modules/gdscript/gdscript_parser.h
+++ b/modules/gdscript/gdscript_parser.h
@@ -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;
diff --git a/modules/gdscript/gdscript_tokenizer.h b/modules/gdscript/gdscript_tokenizer.h
index abacdf0322..e4315f7969 100644
--- a/modules/gdscript/gdscript_tokenizer.h
+++ b/modules/gdscript/gdscript_tokenizer.h
@@ -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"