Skip to content

Commit

Permalink
Variant: add method get_full_type_name and used in many places
Browse files Browse the repository at this point in the history
  • Loading branch information
rune-scape committed Nov 8, 2024
1 parent b00e1cb commit eeaf5eb
Show file tree
Hide file tree
Showing 23 changed files with 172 additions and 59 deletions.
6 changes: 3 additions & 3 deletions core/math/expression.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1278,7 +1278,7 @@ bool Expression::_execute(const Array &p_inputs, Object *p_instance, Expression:
bool valid = true;
Variant::evaluate(op->op, a, b, r_ret, valid);
if (!valid) {
r_error_str = vformat(RTR("Invalid operands to operator %s, %s and %s."), Variant::get_operator_name(op->op), Variant::get_type_name(a.get_type()), Variant::get_type_name(b.get_type()));
r_error_str = vformat(RTR("Invalid operands to operator %s, %s and %s."), Variant::get_operator_name(op->op), a.get_full_type_name(), b.get_full_type_name());
return true;
}

Expand All @@ -1302,7 +1302,7 @@ bool Expression::_execute(const Array &p_inputs, Object *p_instance, Expression:
bool valid;
r_ret = base.get(idx, &valid);
if (!valid) {
r_error_str = vformat(RTR("Invalid index of type %s for base type %s"), Variant::get_type_name(idx.get_type()), Variant::get_type_name(base.get_type()));
r_error_str = vformat(RTR("Invalid index of type %s for base type %s"), idx.get_full_type_name(), base.get_full_type_name());
return true;
}

Expand All @@ -1319,7 +1319,7 @@ bool Expression::_execute(const Array &p_inputs, Object *p_instance, Expression:
bool valid;
r_ret = base.get_named(index->name, valid);
if (!valid) {
r_error_str = vformat(RTR("Invalid named index '%s' for base type %s"), String(index->name), Variant::get_type_name(base.get_type()));
r_error_str = vformat(RTR("Invalid named index '%s' for base type %s"), String(index->name), base.get_full_type_name());
return true;
}

Expand Down
12 changes: 6 additions & 6 deletions core/variant/array.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -235,14 +235,14 @@ void Array::assign(const Array &p_array) {
for (int i = 0; i < size; i++) {
const Variant &element = source[i];
if (element.get_type() != Variant::NIL && (element.get_type() != Variant::OBJECT || !typed.validate_object(element, "assign"))) {
ERR_FAIL_MSG(vformat(R"(Unable to convert array index %d from "%s" to "%s".)", i, Variant::get_type_name(element.get_type()), Variant::get_type_name(typed.type)));
ERR_FAIL_MSG(vformat(R"(Unable to convert array index %d from "%s" to "%s".)", i, element.get_full_type_name(), typed.get_contained_type_name()));
}
}
_p->array = p_array._p->array;
return;
}
if (typed.type == Variant::OBJECT || source_typed.type == Variant::OBJECT) {
ERR_FAIL_MSG(vformat(R"(Cannot assign contents of "Array[%s]" to "Array[%s]".)", Variant::get_type_name(source_typed.type), Variant::get_type_name(typed.type)));
ERR_FAIL_MSG(vformat(R"(Cannot assign contents of "Array[%s]" to "Array[%s]".)", source_typed.get_contained_type_name(), typed.get_contained_type_name()));
}

Vector<Variant> array;
Expand All @@ -258,22 +258,22 @@ void Array::assign(const Array &p_array) {
continue;
}
if (!Variant::can_convert_strict(value->get_type(), typed.type)) {
ERR_FAIL_MSG(vformat(R"(Unable to convert array index %d from "%s" to "%s".)", i, Variant::get_type_name(value->get_type()), Variant::get_type_name(typed.type)));
ERR_FAIL_MSG(vformat(R"(Unable to convert array index %d from "%s" to "%s".)", i, value->get_full_type_name(), typed.get_contained_type_name()));
}
Callable::CallError ce;
Variant::construct(typed.type, data[i], &value, 1, ce);
ERR_FAIL_COND_MSG(ce.error, vformat(R"(Unable to convert array index %d from "%s" to "%s".)", i, Variant::get_type_name(value->get_type()), Variant::get_type_name(typed.type)));
ERR_FAIL_COND_MSG(ce.error, vformat(R"(Unable to convert array index %d from "%s" to "%s".)", i, value->get_full_type_name(), typed.get_contained_type_name()));
}
} else if (Variant::can_convert_strict(source_typed.type, typed.type)) {
// from primitives to different convertible primitives
for (int i = 0; i < size; i++) {
const Variant *value = source + i;
Callable::CallError ce;
Variant::construct(typed.type, data[i], &value, 1, ce);
ERR_FAIL_COND_MSG(ce.error, vformat(R"(Unable to convert array index %d from "%s" to "%s".)", i, Variant::get_type_name(value->get_type()), Variant::get_type_name(typed.type)));
ERR_FAIL_COND_MSG(ce.error, vformat(R"(Unable to convert array index %d from "%s" to "%s".)", i, value->get_full_type_name(), typed.get_contained_type_name()));
}
} else {
ERR_FAIL_MSG(vformat(R"(Cannot assign contents of "Array[%s]" to "Array[%s]".)", Variant::get_type_name(source_typed.type), Variant::get_type_name(typed.type)));
ERR_FAIL_MSG(vformat(R"(Cannot assign contents of "Array[%s]" to "Array[%s]".)", source_typed.get_contained_type_name(), typed.get_contained_type_name()));
}

_p->array = array;
Expand Down
43 changes: 42 additions & 1 deletion core/variant/container_type_validate.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,53 @@
#include "core/object/script_language.h"
#include "core/variant/variant.h"

#include "modules/modules_enabled.gen.h"

#ifdef MODULE_GDSCRIPT_ENABLED
#include "modules/gdscript/gdscript.h"
#endif // MODULE_GDSCRIPT_ENABLED

struct ContainerTypeValidate {
Variant::Type type = Variant::NIL;
StringName class_name;
Ref<Script> script;
const char *where = "container";

String get_contained_type_name() const {
if (type == Variant::NIL) {
return "";
}

String contained_typename;
if (type != Variant::OBJECT) {
contained_typename = Variant::get_type_name(type);
} else {
contained_typename = class_name;
if (contained_typename.is_empty()) {
contained_typename = "Object";
}

if (!script.is_null()) {
String script_name;
#ifdef MODULE_GDSCRIPT_ENABLED
Ref<GDScript> gdscript = script;
if (!gdscript.is_null()) {
script_name = gdscript->get_fully_qualified_name();
} else
#endif // MODULE_GDSCRIPT_ENABLED
{
script_name = script->get_global_name();
if (script_name.is_empty()) {
script_name = script->get_path();
}
}
contained_typename += " (" + script_name + ")";
}
}

return contained_typename;
}

_FORCE_INLINE_ bool can_reference(const ContainerTypeValidate &p_type) const {
if (type != p_type.type) {
return false;
Expand Down Expand Up @@ -94,7 +135,7 @@ struct ContainerTypeValidate {
return true;
}

ERR_FAIL_V_MSG(false, vformat("Attempted to %s a variable of type '%s' into a %s of type '%s'.", String(p_operation), Variant::get_type_name(inout_variant.get_type()), where, Variant::get_type_name(type)));
ERR_FAIL_V_MSG(false, vformat("Attempted to %s a variable of type '%s' into a %s of type '%s'.", String(p_operation), inout_variant.get_full_type_name(), where, get_contained_type_name()));
}

if (type != Variant::OBJECT) {
Expand Down
74 changes: 73 additions & 1 deletion core/variant/variant.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
#include "core/io/marshalls.h"
#include "core/io/resource.h"
#include "core/math/math_funcs.h"
#include "core/object/script_language.h"
#include "core/string/print_string.h"
#include "core/variant/variant_parser.h"

Expand Down Expand Up @@ -176,6 +177,77 @@ String Variant::get_type_name(Variant::Type p_type) {
return "";
}

String Variant::get_full_type_name() const {
switch (get_type()) {
case OBJECT: {
Object *obj = _get_obj().obj;
if (obj == nullptr) {
return "Object (null instance)";
}

ObjectID id = _get_obj().id;
if (!id.is_ref_counted() && ObjectDB::get_instance(id) == nullptr) {
return "Object (previously freed)";
}

String class_name = obj->get_class();
Vector<Pair<Ref<Script>, String>> scripts;
scripts.push_back({ Object::cast_to<Script>(obj), "{0}[{1}]" });
scripts.push_back({ obj->get_script(), "{0} ({1})" });

for (const Pair<Ref<Script>, String> &script_and_fmt : scripts) {
const Ref<Script> &script = script_and_fmt.first;
const String &fmt = script_and_fmt.second;
if (script.is_null()) {
continue;
}

String script_name = script->get_global_name();
if (script_name.is_empty()) {
script_name = script->get_path();
}
if (!script_name.is_empty()) {
Array format_values;
format_values.push_back(class_name);
format_values.push_back(script_name);
class_name = fmt.format(format_values);
}
}

return class_name;
}
case ARRAY: {
const Array &arr = *reinterpret_cast<const Array *>(_data._mem);
if (!arr.is_typed()) {
return "Array";
}

String contained_typename;
if (arr.get_typed_builtin() != OBJECT) {
contained_typename = get_type_name(get_type());
} else {
contained_typename = arr.get_typed_class_name();
if (contained_typename.is_empty()) {
contained_typename = "Object";
}
Ref<Script> script = arr.get_typed_script();
if (!script.is_null()) {
String script_name = script->get_global_name();
if (script_name.is_empty()) {
script_name = script->get_path();
}
contained_typename += " (" + script_name + ")";
}
}

return "Array[" + contained_typename + "]";
}
default: {
return get_type_name(get_type());
}
}
}

bool Variant::can_convert(Variant::Type p_type_from, Variant::Type p_type_to) {
if (p_type_from == p_type_to) {
return true;
Expand Down Expand Up @@ -3632,7 +3704,7 @@ String Variant::get_call_error_text(Object *p_base, const StringName &p_method,
if (ce.error == Callable::CallError::CALL_ERROR_INVALID_ARGUMENT) {
int errorarg = ce.argument;
if (p_argptrs) {
err_text = "Cannot convert argument " + itos(errorarg + 1) + " from " + Variant::get_type_name(p_argptrs[errorarg]->get_type()) + " to " + Variant::get_type_name(Variant::Type(ce.expected));
err_text = "Cannot convert argument " + itos(errorarg + 1) + " from " + p_argptrs[errorarg]->get_full_type_name() + " to " + Variant::get_type_name(Variant::Type(ce.expected));
} else {
err_text = "Cannot convert argument " + itos(errorarg + 1) + " from [missing argptr, type unknown] to " + Variant::get_type_name(Variant::Type(ce.expected));
}
Expand Down
1 change: 1 addition & 0 deletions core/variant/variant.h
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,7 @@ class Variant {
return type;
}
static String get_type_name(Variant::Type p_type);
String get_full_type_name() const;
static bool can_convert(Type p_type_from, Type p_type_to);
static bool can_convert_strict(Type p_type_from, Type p_type_to);
static bool is_type_shared(Variant::Type p_type);
Expand Down
2 changes: 1 addition & 1 deletion editor/animation_track_editor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2807,7 +2807,7 @@ String AnimationTrackEdit::get_tooltip(const Point2 &p_pos) const {
} break;
case Animation::TYPE_VALUE: {
const Variant &v = animation->track_get_key_value(track, key_idx);
text += TTR("Type:") + " " + Variant::get_type_name(v.get_type()) + "\n";
text += TTR("Type:") + " " + v.get_full_type_name() + "\n";
Variant::Type valid_type = Variant::NIL;
text += TTR("Value:") + " " + String(v);
if (!_is_value_key_valid(v, valid_type)) {
Expand Down
2 changes: 1 addition & 1 deletion editor/connections_dialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -989,7 +989,7 @@ void ConnectionsDock::_make_or_edit_connection() {
PackedStringArray script_function_args = connect_dialog->get_signal_args();
script_function_args.resize(script_function_args.size() - cd.unbinds);
for (int i = 0; i < cd.binds.size(); i++) {
script_function_args.push_back("extra_arg_" + itos(i) + ":" + Variant::get_type_name(cd.binds[i].get_type()));
script_function_args.push_back("extra_arg_" + itos(i) + ":" + cd.binds[i].get_full_type_name());
}

EditorNode::get_singleton()->emit_signal(SNAME("script_add_function_request"), target, cd.method, script_function_args);
Expand Down
6 changes: 3 additions & 3 deletions editor/debugger/debug_adapter/debug_adapter_protocol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -434,7 +434,7 @@ int DebugAdapterProtocol::parse_variant(const Variant &p_var) {
for (int i = 0; i < array.size(); i++) {
DAP::Variable var;
var.name = itos(i);
var.type = Variant::get_type_name(array[i].get_type());
var.type = array[i].get_full_type_name();
var.value = array[i];
var.variablesReference = parse_variant(array[i]);
arr.push_back(var.to_json());
Expand All @@ -451,7 +451,7 @@ int DebugAdapterProtocol::parse_variant(const Variant &p_var) {
DAP::Variable var;
var.name = dictionary.get_key_at_index(i);
Variant value = dictionary.get_value_at_index(i);
var.type = Variant::get_type_name(value.get_type());
var.type = value.get_full_type_name();
var.value = value;
var.variablesReference = parse_variant(value);
arr.push_back(var.to_json());
Expand Down Expand Up @@ -1157,7 +1157,7 @@ void DebugAdapterProtocol::on_debug_stack_frame_var(const Array &p_data) {

variable.name = stack_var.name;
variable.value = stack_var.value;
variable.type = Variant::get_type_name(stack_var.value.get_type());
variable.type = stack_var.value.get_full_type_name();
variable.variablesReference = parse_variant(stack_var.value);

variable_list.find(var_id)->value.push_back(variable.to_json());
Expand Down
8 changes: 4 additions & 4 deletions modules/gdscript/gdscript_analyzer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1637,7 +1637,7 @@ void GDScriptAnalyzer::resolve_annotation(GDScriptParser::AnnotationNode *p_anno
Variant::construct(argument_info.type, converted_to, &converted_from, 1, call_error);

if (call_error.error != Callable::CallError::CALL_OK) {
push_error(vformat(R"(Cannot convert argument %d of annotation "%s" from "%s" to "%s".)", i + 1, p_annotation->name, Variant::get_type_name(value.get_type()), Variant::get_type_name(argument_info.type)), argument);
push_error(vformat(R"(Cannot convert argument %d of annotation "%s" from "%s" to "%s".)", i + 1, p_annotation->name, value.get_full_type_name(), Variant::get_type_name(argument_info.type)), argument);
return;
}

Expand Down Expand Up @@ -2135,7 +2135,7 @@ void GDScriptAnalyzer::resolve_for(GDScriptParser::ForNode *p_for) {
if (argument->is_constant) {
if (argument->reduced_value.get_type() != Variant::INT && argument->reduced_value.get_type() != Variant::FLOAT) {
can_reduce = false;
push_error(vformat(R"*(Invalid argument for "range()" call. Argument %d should be int or float but "%s" was given.)*", i + 1, Variant::get_type_name(argument->reduced_value.get_type())), argument);
push_error(vformat(R"*(Invalid argument for "range()" call. Argument %d should be int or float but "%s" was given.)*", i + 1, argument->reduced_value.get_full_type_name()), argument);
}
if (can_reduce) {
args.write[i] = argument->reduced_value;
Expand Down Expand Up @@ -3036,8 +3036,8 @@ void GDScriptAnalyzer::reduce_binary_op(GDScriptParser::BinaryOpNode *p_binary_o
} else {
push_error(vformat(R"(Invalid operands to operator %s, %s and %s.)",
Variant::get_operator_name(p_binary_op->variant_op),
Variant::get_type_name(p_binary_op->left_operand->reduced_value.get_type()),
Variant::get_type_name(p_binary_op->right_operand->reduced_value.get_type())),
p_binary_op->left_operand->reduced_value.get_full_type_name(),
p_binary_op->right_operand->reduced_value.get_full_type_name()),
p_binary_op);
}
}
Expand Down
2 changes: 1 addition & 1 deletion modules/gdscript/gdscript_parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -884,7 +884,7 @@ void GDScriptParser::parse_extends() {

if (match(GDScriptTokenizer::Token::LITERAL)) {
if (previous.literal.get_type() != Variant::STRING) {
push_error(vformat(R"(Only strings or identifiers can be used after "extends", found "%s" instead.)", Variant::get_type_name(previous.literal.get_type())));
push_error(vformat(R"(Only strings or identifiers can be used after "extends", found "%s" instead.)", previous.literal.get_full_type_name()));
}
current_class->extends_path = previous.literal;

Expand Down
2 changes: 1 addition & 1 deletion modules/gdscript/gdscript_utility_functions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -442,7 +442,7 @@ struct GDScriptUtilityFunctionsDefinitions {
*r_ret = d.size();
} break;
default: {
*r_ret = vformat(RTR("Value of type '%s' can't provide a length."), Variant::get_type_name(p_args[0]->get_type()));
*r_ret = vformat(RTR("Value of type '%s' can't provide a length."), p_args[0]->get_full_type_name());
r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
r_error.expected = Variant::NIL;
Expand Down
Loading

0 comments on commit eeaf5eb

Please sign in to comment.