Merge pull request #51671 from RandomShaper/fix_gdscript_crash

Fix some GDScript bugs
This commit is contained in:
George Marques 2021-09-17 12:29:40 -03:00 committed by GitHub
commit b8fdeb6467
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 62 additions and 15 deletions

View file

@ -1187,12 +1187,28 @@ void GDScriptAnalyzer::resolve_for(GDScriptParser::ForNode *p_for) {
}
}
if (!list_resolved) {
GDScriptParser::DataType variable_type;
if (list_resolved) {
variable_type.type_source = GDScriptParser::DataType::ANNOTATED_INFERRED;
variable_type.kind = GDScriptParser::DataType::BUILTIN;
variable_type.builtin_type = Variant::INT; // Can this ever be a float or something else?
p_for->variable->set_datatype(variable_type);
} else {
resolve_node(p_for->list);
if (p_for->list->datatype.has_container_element_type()) {
variable_type = p_for->list->datatype.get_container_element_type();
variable_type.type_source = GDScriptParser::DataType::ANNOTATED_INFERRED;
} else if (p_for->list->datatype.is_typed_container_type()) {
variable_type = p_for->list->datatype.get_typed_container_type();
variable_type.type_source = GDScriptParser::DataType::ANNOTATED_INFERRED;
} else {
// Last resort
// TODO: Must other cases be handled? Must we mark as unsafe?
variable_type.type_source = GDScriptParser::DataType::UNDETECTED;
variable_type.kind = GDScriptParser::DataType::VARIANT;
}
}
// TODO: If list is a typed array, the variable should be an element.
// Also applicable for constant range() (so variable is int or float).
p_for->variable->set_datatype(variable_type);
resolve_suite(p_for->loop);
p_for->set_datatype(p_for->loop->get_datatype());
@ -1480,8 +1496,7 @@ void GDScriptAnalyzer::resolve_parameter(GDScriptParser::ParameterNode *p_parame
}
if (p_parameter->datatype_specifier != nullptr) {
resolve_datatype(p_parameter->datatype_specifier);
result = p_parameter->datatype_specifier->get_datatype();
result = resolve_datatype(p_parameter->datatype_specifier);
result.is_meta_type = false;
if (p_parameter->default_value != nullptr) {

View file

@ -51,7 +51,9 @@ GDScriptParser *GDScriptParserRef::get_parser() const {
Error GDScriptParserRef::raise_status(Status p_new_status) {
ERR_FAIL_COND_V(parser == nullptr, ERR_INVALID_DATA);
Error result = OK;
if (result != OK) {
return result;
}
while (p_new_status > status) {
switch (status) {
@ -86,14 +88,6 @@ Error GDScriptParserRef::raise_status(Status p_new_status) {
}
}
if (result != OK) {
if (parser != nullptr) {
memdelete(parser);
parser = nullptr;
}
if (analyzer != nullptr) {
memdelete(analyzer);
analyzer = nullptr;
}
return result;
}
}

View file

@ -54,6 +54,7 @@ private:
GDScriptParser *parser = nullptr;
GDScriptAnalyzer *analyzer = nullptr;
Status status = EMPTY;
Error result = OK;
String path;
friend class GDScriptCache;

View file

@ -3587,6 +3587,39 @@ String GDScriptParser::DataType::to_string() const {
ERR_FAIL_V_MSG("<unresolved type", "Kind set outside the enum range.");
}
static Variant::Type _variant_type_to_typed_array_element_type(Variant::Type p_type) {
switch (p_type) {
case Variant::PACKED_BYTE_ARRAY:
case Variant::PACKED_INT32_ARRAY:
case Variant::PACKED_INT64_ARRAY:
return Variant::INT;
case Variant::PACKED_FLOAT32_ARRAY:
case Variant::PACKED_FLOAT64_ARRAY:
return Variant::FLOAT;
case Variant::PACKED_STRING_ARRAY:
return Variant::STRING;
case Variant::PACKED_VECTOR2_ARRAY:
return Variant::VECTOR2;
case Variant::PACKED_VECTOR3_ARRAY:
return Variant::VECTOR3;
case Variant::PACKED_COLOR_ARRAY:
return Variant::COLOR;
default:
return Variant::NIL;
}
}
bool GDScriptParser::DataType::is_typed_container_type() const {
return kind == GDScriptParser::DataType::BUILTIN && _variant_type_to_typed_array_element_type(builtin_type) != Variant::NIL;
}
GDScriptParser::DataType GDScriptParser::DataType::get_typed_container_type() const {
GDScriptParser::DataType type;
type.kind = GDScriptParser::DataType::BUILTIN;
type.builtin_type = _variant_type_to_typed_array_element_type(builtin_type);
return type;
}
/*---------- PRETTY PRINT FOR DEBUG ----------*/
#ifdef DEBUG_ENABLED

View file

@ -161,6 +161,10 @@ public:
container_element_type = nullptr;
}
bool is_typed_container_type() const;
GDScriptParser::DataType get_typed_container_type() const;
bool operator==(const DataType &p_other) const {
if (type_source == UNDETECTED || p_other.type_source == UNDETECTED) {
return true; // Can be consireded equal for parsing purposes.