Mono: BindingsGenerator enum fixes
- Make enums have an unique signature name of int. This means that when generating internal methods, there is no difference between different enums types nor between enums and int. This way enums can re-use internal methods. - Make type resolver fallback to int if a type is not found and it's an enum.
This commit is contained in:
parent
1226720c01
commit
fbc808012f
|
@ -248,14 +248,14 @@ void BindingsGenerator::_generate_method_icalls(const TypeInterface &p_itype) {
|
||||||
if (imethod.is_virtual)
|
if (imethod.is_virtual)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
const TypeInterface *return_type = _get_type_by_name_or_placeholder(imethod.return_type);
|
const TypeInterface *return_type = _get_type_or_placeholder(imethod.return_type);
|
||||||
|
|
||||||
String im_sig;
|
String im_sig;
|
||||||
String im_unique_sig;
|
String im_unique_sig;
|
||||||
|
|
||||||
if (p_itype.is_object_type) {
|
if (p_itype.is_object_type) {
|
||||||
im_sig += "IntPtr " CS_PARAM_METHODBIND ", ";
|
im_sig += "IntPtr " CS_PARAM_METHODBIND ", ";
|
||||||
im_unique_sig += imethod.return_type.operator String() + ",IntPtr,IntPtr";
|
im_unique_sig += imethod.return_type.cname.operator String() + ",IntPtr,IntPtr";
|
||||||
}
|
}
|
||||||
|
|
||||||
im_sig += "IntPtr " CS_PARAM_INSTANCE;
|
im_sig += "IntPtr " CS_PARAM_INSTANCE;
|
||||||
|
@ -263,7 +263,7 @@ void BindingsGenerator::_generate_method_icalls(const TypeInterface &p_itype) {
|
||||||
// Get arguments information
|
// Get arguments information
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (const List<ArgumentInterface>::Element *F = imethod.arguments.front(); F; F = F->next()) {
|
for (const List<ArgumentInterface>::Element *F = imethod.arguments.front(); F; F = F->next()) {
|
||||||
const TypeInterface *arg_type = _get_type_by_name_or_placeholder(F->get().type);
|
const TypeInterface *arg_type = _get_type_or_placeholder(F->get().type);
|
||||||
|
|
||||||
im_sig += ", ";
|
im_sig += ", ";
|
||||||
im_sig += arg_type->im_type_in;
|
im_sig += arg_type->im_type_in;
|
||||||
|
@ -1069,12 +1069,12 @@ Error BindingsGenerator::_generate_cs_property(const BindingsGenerator::TypeInte
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getter && setter) {
|
if (getter && setter) {
|
||||||
ERR_FAIL_COND_V(getter->return_type != setter->arguments.back()->get().type, ERR_BUG);
|
ERR_FAIL_COND_V(getter->return_type.cname != setter->arguments.back()->get().type.cname, ERR_BUG);
|
||||||
}
|
}
|
||||||
|
|
||||||
StringName proptype_name = getter ? getter->return_type : setter->arguments.back()->get().type;
|
const TypeReference &proptype_name = getter ? getter->return_type : setter->arguments.back()->get().type;
|
||||||
|
|
||||||
const TypeInterface *prop_itype = _get_type_by_name_or_null(proptype_name);
|
const TypeInterface *prop_itype = _get_type_or_null(proptype_name);
|
||||||
ERR_FAIL_NULL_V(prop_itype, ERR_BUG); // Property type not found
|
ERR_FAIL_NULL_V(prop_itype, ERR_BUG); // Property type not found
|
||||||
|
|
||||||
String prop_proxy_name = escape_csharp_keyword(snake_to_pascal_case(p_iprop.cname));
|
String prop_proxy_name = escape_csharp_keyword(snake_to_pascal_case(p_iprop.cname));
|
||||||
|
@ -1122,9 +1122,9 @@ Error BindingsGenerator::_generate_cs_property(const BindingsGenerator::TypeInte
|
||||||
p_output.push_back(getter->proxy_name + "(");
|
p_output.push_back(getter->proxy_name + "(");
|
||||||
if (p_iprop.index != -1) {
|
if (p_iprop.index != -1) {
|
||||||
const ArgumentInterface &idx_arg = getter->arguments.front()->get();
|
const ArgumentInterface &idx_arg = getter->arguments.front()->get();
|
||||||
if (idx_arg.type != name_cache.type_int) {
|
if (idx_arg.type.cname != name_cache.type_int) {
|
||||||
// Assume the index parameter is an enum
|
// Assume the index parameter is an enum
|
||||||
const TypeInterface *idx_arg_type = _get_type_by_name_or_null(idx_arg.type);
|
const TypeInterface *idx_arg_type = _get_type_or_null(idx_arg.type);
|
||||||
CRASH_COND(idx_arg_type == NULL);
|
CRASH_COND(idx_arg_type == NULL);
|
||||||
p_output.push_back("(" + idx_arg_type->proxy_name + ")" + itos(p_iprop.index));
|
p_output.push_back("(" + idx_arg_type->proxy_name + ")" + itos(p_iprop.index));
|
||||||
} else {
|
} else {
|
||||||
|
@ -1139,9 +1139,9 @@ Error BindingsGenerator::_generate_cs_property(const BindingsGenerator::TypeInte
|
||||||
p_output.push_back(setter->proxy_name + "(");
|
p_output.push_back(setter->proxy_name + "(");
|
||||||
if (p_iprop.index != -1) {
|
if (p_iprop.index != -1) {
|
||||||
const ArgumentInterface &idx_arg = setter->arguments.front()->get();
|
const ArgumentInterface &idx_arg = setter->arguments.front()->get();
|
||||||
if (idx_arg.type != name_cache.type_int) {
|
if (idx_arg.type.cname != name_cache.type_int) {
|
||||||
// Assume the index parameter is an enum
|
// Assume the index parameter is an enum
|
||||||
const TypeInterface *idx_arg_type = _get_type_by_name_or_null(idx_arg.type);
|
const TypeInterface *idx_arg_type = _get_type_or_null(idx_arg.type);
|
||||||
CRASH_COND(idx_arg_type == NULL);
|
CRASH_COND(idx_arg_type == NULL);
|
||||||
p_output.push_back("(" + idx_arg_type->proxy_name + ")" + itos(p_iprop.index) + ", ");
|
p_output.push_back("(" + idx_arg_type->proxy_name + ")" + itos(p_iprop.index) + ", ");
|
||||||
} else {
|
} else {
|
||||||
|
@ -1158,7 +1158,7 @@ Error BindingsGenerator::_generate_cs_property(const BindingsGenerator::TypeInte
|
||||||
|
|
||||||
Error BindingsGenerator::_generate_cs_method(const BindingsGenerator::TypeInterface &p_itype, const BindingsGenerator::MethodInterface &p_imethod, int &p_method_bind_count, List<String> &p_output) {
|
Error BindingsGenerator::_generate_cs_method(const BindingsGenerator::TypeInterface &p_itype, const BindingsGenerator::MethodInterface &p_imethod, int &p_method_bind_count, List<String> &p_output) {
|
||||||
|
|
||||||
const TypeInterface *return_type = _get_type_by_name_or_placeholder(p_imethod.return_type);
|
const TypeInterface *return_type = _get_type_or_placeholder(p_imethod.return_type);
|
||||||
|
|
||||||
String method_bind_field = "method_bind_" + itos(p_method_bind_count);
|
String method_bind_field = "method_bind_" + itos(p_method_bind_count);
|
||||||
|
|
||||||
|
@ -1175,7 +1175,7 @@ Error BindingsGenerator::_generate_cs_method(const BindingsGenerator::TypeInterf
|
||||||
// Retrieve information from the arguments
|
// Retrieve information from the arguments
|
||||||
for (const List<ArgumentInterface>::Element *F = p_imethod.arguments.front(); F; F = F->next()) {
|
for (const List<ArgumentInterface>::Element *F = p_imethod.arguments.front(); F; F = F->next()) {
|
||||||
const ArgumentInterface &iarg = F->get();
|
const ArgumentInterface &iarg = F->get();
|
||||||
const TypeInterface *arg_type = _get_type_by_name_or_placeholder(iarg.type);
|
const TypeInterface *arg_type = _get_type_or_placeholder(iarg.type);
|
||||||
|
|
||||||
// Add the current arguments to the signature
|
// Add the current arguments to the signature
|
||||||
// If the argument has a default value which is not a constant, we will make it Nullable
|
// If the argument has a default value which is not a constant, we will make it Nullable
|
||||||
|
@ -1328,21 +1328,19 @@ Error BindingsGenerator::_generate_cs_method(const BindingsGenerator::TypeInterf
|
||||||
const InternalCall *im_icall = match->value();
|
const InternalCall *im_icall = match->value();
|
||||||
|
|
||||||
String im_call = im_icall->editor_only ? BINDINGS_CLASS_NATIVECALLS_EDITOR : BINDINGS_CLASS_NATIVECALLS;
|
String im_call = im_icall->editor_only ? BINDINGS_CLASS_NATIVECALLS_EDITOR : BINDINGS_CLASS_NATIVECALLS;
|
||||||
im_call += "." + im_icall->name + "(" + icall_params + ");\n";
|
im_call += "." + im_icall->name + "(" + icall_params + ")";
|
||||||
|
|
||||||
if (p_imethod.arguments.size())
|
if (p_imethod.arguments.size())
|
||||||
p_output.push_back(cs_in_statements);
|
p_output.push_back(cs_in_statements);
|
||||||
|
|
||||||
if (return_type->cname == name_cache.type_void) {
|
if (return_type->cname == name_cache.type_void) {
|
||||||
p_output.push_back(im_call);
|
p_output.push_back(im_call + ";\n");
|
||||||
} else if (return_type->cs_out.empty()) {
|
} else if (return_type->cs_out.empty()) {
|
||||||
p_output.push_back("return " + im_call);
|
p_output.push_back("return " + im_call + ";\n");
|
||||||
} else {
|
} else {
|
||||||
p_output.push_back(return_type->im_type_out);
|
|
||||||
p_output.push_back(" " LOCAL_RET " = ");
|
|
||||||
p_output.push_back(im_call);
|
|
||||||
p_output.push_back(INDENT3);
|
p_output.push_back(INDENT3);
|
||||||
p_output.push_back(sformat(return_type->cs_out, LOCAL_RET) + "\n");
|
p_output.push_back(sformat(return_type->cs_out, im_call, return_type->cs_type, return_type->im_type_out));
|
||||||
|
p_output.push_back("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
p_output.push_back(CLOSE_BLOCK_L2);
|
p_output.push_back(CLOSE_BLOCK_L2);
|
||||||
|
@ -1540,9 +1538,9 @@ Error BindingsGenerator::_generate_glue_method(const BindingsGenerator::TypeInte
|
||||||
if (p_imethod.is_virtual)
|
if (p_imethod.is_virtual)
|
||||||
return OK; // Ignore
|
return OK; // Ignore
|
||||||
|
|
||||||
bool ret_void = p_imethod.return_type == name_cache.type_void;
|
bool ret_void = p_imethod.return_type.cname == name_cache.type_void;
|
||||||
|
|
||||||
const TypeInterface *return_type = _get_type_by_name_or_placeholder(p_imethod.return_type);
|
const TypeInterface *return_type = _get_type_or_placeholder(p_imethod.return_type);
|
||||||
|
|
||||||
String argc_str = itos(p_imethod.arguments.size());
|
String argc_str = itos(p_imethod.arguments.size());
|
||||||
|
|
||||||
|
@ -1554,7 +1552,7 @@ Error BindingsGenerator::_generate_glue_method(const BindingsGenerator::TypeInte
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (const List<ArgumentInterface>::Element *F = p_imethod.arguments.front(); F; F = F->next()) {
|
for (const List<ArgumentInterface>::Element *F = p_imethod.arguments.front(); F; F = F->next()) {
|
||||||
const ArgumentInterface &iarg = F->get();
|
const ArgumentInterface &iarg = F->get();
|
||||||
const TypeInterface *arg_type = _get_type_by_name_or_placeholder(iarg.type);
|
const TypeInterface *arg_type = _get_type_or_placeholder(iarg.type);
|
||||||
|
|
||||||
String c_param_name = "arg" + itos(i + 1);
|
String c_param_name = "arg" + itos(i + 1);
|
||||||
|
|
||||||
|
@ -1695,42 +1693,49 @@ Error BindingsGenerator::_generate_glue_method(const BindingsGenerator::TypeInte
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
const BindingsGenerator::TypeInterface *BindingsGenerator::_get_type_by_name_or_null(const StringName &p_cname) {
|
const BindingsGenerator::TypeInterface *BindingsGenerator::_get_type_or_null(const TypeReference &p_typeref) {
|
||||||
|
|
||||||
const Map<StringName, TypeInterface>::Element *builtin_type_match = builtin_types.find(p_cname);
|
const Map<StringName, TypeInterface>::Element *builtin_type_match = builtin_types.find(p_typeref.cname);
|
||||||
|
|
||||||
if (builtin_type_match)
|
if (builtin_type_match)
|
||||||
return &builtin_type_match->get();
|
return &builtin_type_match->get();
|
||||||
|
|
||||||
const OrderedHashMap<StringName, TypeInterface>::Element obj_type_match = obj_types.find(p_cname);
|
const OrderedHashMap<StringName, TypeInterface>::Element obj_type_match = obj_types.find(p_typeref.cname);
|
||||||
|
|
||||||
if (obj_type_match)
|
if (obj_type_match)
|
||||||
return &obj_type_match.get();
|
return &obj_type_match.get();
|
||||||
|
|
||||||
const Map<StringName, TypeInterface>::Element *enum_match = enum_types.find(p_cname);
|
if (p_typeref.is_enum) {
|
||||||
|
const Map<StringName, TypeInterface>::Element *enum_match = enum_types.find(p_typeref.cname);
|
||||||
|
|
||||||
if (enum_match)
|
if (enum_match)
|
||||||
return &enum_match->get();
|
return &enum_match->get();
|
||||||
|
|
||||||
|
// Enum not found. Most likely because none of its constants were bound, so it's empty. That's fine. Use int instead.
|
||||||
|
const Map<StringName, TypeInterface>::Element *int_match = builtin_types.find(name_cache.type_int);
|
||||||
|
ERR_FAIL_NULL_V(int_match, NULL);
|
||||||
|
return &int_match->get();
|
||||||
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
const BindingsGenerator::TypeInterface *BindingsGenerator::_get_type_by_name_or_placeholder(const StringName &p_cname) {
|
const BindingsGenerator::TypeInterface *BindingsGenerator::_get_type_or_placeholder(const TypeReference &p_typeref) {
|
||||||
|
|
||||||
const TypeInterface *found = _get_type_by_name_or_null(p_cname);
|
const TypeInterface *found = _get_type_or_null(p_typeref);
|
||||||
|
|
||||||
if (found)
|
if (found)
|
||||||
return found;
|
return found;
|
||||||
|
|
||||||
ERR_PRINTS(String() + "Type not found. Creating placeholder: " + p_cname.operator String());
|
ERR_PRINTS(String() + "Type not found. Creating placeholder: " + p_typeref.cname.operator String());
|
||||||
|
|
||||||
const Map<StringName, TypeInterface>::Element *match = placeholder_types.find(p_cname);
|
const Map<StringName, TypeInterface>::Element *match = placeholder_types.find(p_typeref.cname);
|
||||||
|
|
||||||
if (match)
|
if (match)
|
||||||
return &match->get();
|
return &match->get();
|
||||||
|
|
||||||
TypeInterface placeholder;
|
TypeInterface placeholder;
|
||||||
TypeInterface::create_placeholder_type(placeholder, p_cname);
|
TypeInterface::create_placeholder_type(placeholder, p_typeref.cname);
|
||||||
|
|
||||||
return &placeholder_types.insert(placeholder.cname, placeholder)->get();
|
return &placeholder_types.insert(placeholder.cname, placeholder)->get();
|
||||||
}
|
}
|
||||||
|
@ -1874,7 +1879,7 @@ void BindingsGenerator::_populate_object_type_interfaces() {
|
||||||
// The method Object.free is registered as a virtual method, but without the virtual flag.
|
// The method Object.free is registered as a virtual method, but without the virtual flag.
|
||||||
// This is because this method is not supposed to be overridden, but called.
|
// This is because this method is not supposed to be overridden, but called.
|
||||||
// We assume the return type is void.
|
// We assume the return type is void.
|
||||||
imethod.return_type = name_cache.type_void;
|
imethod.return_type.cname = name_cache.type_void;
|
||||||
|
|
||||||
// Actually, more methods like this may be added in the future,
|
// Actually, more methods like this may be added in the future,
|
||||||
// which could actually will return something different.
|
// which could actually will return something different.
|
||||||
|
@ -1889,21 +1894,22 @@ void BindingsGenerator::_populate_object_type_interfaces() {
|
||||||
} else {
|
} else {
|
||||||
ERR_PRINTS("Missing MethodBind for non-virtual method: " + itype.name + "." + imethod.name);
|
ERR_PRINTS("Missing MethodBind for non-virtual method: " + itype.name + "." + imethod.name);
|
||||||
}
|
}
|
||||||
} else if (return_info.type == Variant::INT && return_info.usage & PROPERTY_USAGE_CLASS_IS_ENUM) { // TODO redundant?
|
} else if (return_info.type == Variant::INT && return_info.usage & PROPERTY_USAGE_CLASS_IS_ENUM) {
|
||||||
imethod.return_type = return_info.class_name;
|
imethod.return_type.cname = return_info.class_name;
|
||||||
|
imethod.return_type.is_enum = true;
|
||||||
} else if (return_info.class_name != StringName()) {
|
} else if (return_info.class_name != StringName()) {
|
||||||
imethod.return_type = return_info.class_name;
|
imethod.return_type.cname = return_info.class_name;
|
||||||
} else if (return_info.hint == PROPERTY_HINT_RESOURCE_TYPE) {
|
} else if (return_info.hint == PROPERTY_HINT_RESOURCE_TYPE) {
|
||||||
imethod.return_type = return_info.hint_string;
|
imethod.return_type.cname = return_info.hint_string;
|
||||||
} else if (return_info.type == Variant::NIL && return_info.usage & PROPERTY_USAGE_NIL_IS_VARIANT) {
|
} else if (return_info.type == Variant::NIL && return_info.usage & PROPERTY_USAGE_NIL_IS_VARIANT) {
|
||||||
imethod.return_type = name_cache.type_Variant;
|
imethod.return_type.cname = name_cache.type_Variant;
|
||||||
} else if (return_info.type == Variant::NIL) {
|
} else if (return_info.type == Variant::NIL) {
|
||||||
imethod.return_type = name_cache.type_void;
|
imethod.return_type.cname = name_cache.type_void;
|
||||||
} else {
|
} else {
|
||||||
imethod.return_type = Variant::get_type_name(return_info.type);
|
imethod.return_type.cname = Variant::get_type_name(return_info.type);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!itype.requires_collections && imethod.return_type == name_cache.type_Dictionary)
|
if (!itype.requires_collections && imethod.return_type.cname == name_cache.type_Dictionary)
|
||||||
itype.requires_collections = true;
|
itype.requires_collections = true;
|
||||||
|
|
||||||
for (int i = 0; i < argc; i++) {
|
for (int i = 0; i < argc; i++) {
|
||||||
|
@ -1912,21 +1918,22 @@ void BindingsGenerator::_populate_object_type_interfaces() {
|
||||||
ArgumentInterface iarg;
|
ArgumentInterface iarg;
|
||||||
iarg.name = arginfo.name;
|
iarg.name = arginfo.name;
|
||||||
|
|
||||||
if (arginfo.type == Variant::INT && arginfo.usage & PROPERTY_USAGE_CLASS_IS_ENUM) { // TODO redundant?
|
if (arginfo.type == Variant::INT && arginfo.usage & PROPERTY_USAGE_CLASS_IS_ENUM) {
|
||||||
iarg.type = arginfo.class_name;
|
iarg.type.cname = arginfo.class_name;
|
||||||
|
iarg.type.is_enum = true;
|
||||||
} else if (arginfo.class_name != StringName()) {
|
} else if (arginfo.class_name != StringName()) {
|
||||||
iarg.type = arginfo.class_name;
|
iarg.type.cname = arginfo.class_name;
|
||||||
} else if (arginfo.hint == PROPERTY_HINT_RESOURCE_TYPE) {
|
} else if (arginfo.hint == PROPERTY_HINT_RESOURCE_TYPE) {
|
||||||
iarg.type = arginfo.hint_string;
|
iarg.type.cname = arginfo.hint_string;
|
||||||
} else if (arginfo.type == Variant::NIL) {
|
} else if (arginfo.type == Variant::NIL) {
|
||||||
iarg.type = name_cache.type_Variant;
|
iarg.type.cname = name_cache.type_Variant;
|
||||||
} else {
|
} else {
|
||||||
iarg.type = Variant::get_type_name(arginfo.type);
|
iarg.type.cname = Variant::get_type_name(arginfo.type);
|
||||||
}
|
}
|
||||||
|
|
||||||
iarg.name = escape_csharp_keyword(snake_to_camel_case(iarg.name));
|
iarg.name = escape_csharp_keyword(snake_to_camel_case(iarg.name));
|
||||||
|
|
||||||
if (!itype.requires_collections && iarg.type == name_cache.type_Dictionary)
|
if (!itype.requires_collections && iarg.type.cname == name_cache.type_Dictionary)
|
||||||
itype.requires_collections = true;
|
itype.requires_collections = true;
|
||||||
|
|
||||||
if (m && m->has_default_argument(i)) {
|
if (m && m->has_default_argument(i)) {
|
||||||
|
@ -1938,7 +1945,7 @@ void BindingsGenerator::_populate_object_type_interfaces() {
|
||||||
|
|
||||||
if (imethod.is_vararg) {
|
if (imethod.is_vararg) {
|
||||||
ArgumentInterface ivararg;
|
ArgumentInterface ivararg;
|
||||||
ivararg.type = name_cache.type_VarArg;
|
ivararg.type.cname = name_cache.type_VarArg;
|
||||||
ivararg.name = "@args";
|
ivararg.name = "@args";
|
||||||
imethod.add_argument(ivararg);
|
imethod.add_argument(ivararg);
|
||||||
}
|
}
|
||||||
|
@ -2023,17 +2030,11 @@ void BindingsGenerator::_populate_object_type_interfaces() {
|
||||||
itype.enums.push_back(ienum);
|
itype.enums.push_back(ienum);
|
||||||
|
|
||||||
TypeInterface enum_itype;
|
TypeInterface enum_itype;
|
||||||
|
enum_itype.is_enum = true;
|
||||||
enum_itype.name = itype.name + "." + String(*k);
|
enum_itype.name = itype.name + "." + String(*k);
|
||||||
enum_itype.cname = StringName(enum_itype.name);
|
enum_itype.cname = StringName(enum_itype.name);
|
||||||
enum_itype.proxy_name = itype.proxy_name + "." + enum_proxy_name;
|
enum_itype.proxy_name = itype.proxy_name + "." + enum_proxy_name;
|
||||||
enum_itype.c_arg_in = "&%s";
|
TypeInterface::postsetup_enum_type(enum_itype);
|
||||||
enum_itype.c_type = "int";
|
|
||||||
enum_itype.c_type_in = "int";
|
|
||||||
enum_itype.c_type_out = "int";
|
|
||||||
enum_itype.cs_type = enum_itype.proxy_name;
|
|
||||||
enum_itype.im_type_in = enum_itype.proxy_name;
|
|
||||||
enum_itype.im_type_out = enum_itype.proxy_name;
|
|
||||||
enum_itype.class_doc = &EditorHelp::get_doc_data()->class_list[enum_itype.proxy_name];
|
|
||||||
enum_types.insert(enum_itype.cname, enum_itype);
|
enum_types.insert(enum_itype.cname, enum_itype);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2068,7 +2069,7 @@ void BindingsGenerator::_default_argument_from_variant(const Variant &p_val, Arg
|
||||||
|
|
||||||
switch (p_val.get_type()) {
|
switch (p_val.get_type()) {
|
||||||
case Variant::NIL:
|
case Variant::NIL:
|
||||||
if (ClassDB::class_exists(r_iarg.type)) {
|
if (ClassDB::class_exists(r_iarg.type.cname)) {
|
||||||
// Object type
|
// Object type
|
||||||
r_iarg.default_argument = "null";
|
r_iarg.default_argument = "null";
|
||||||
} else {
|
} else {
|
||||||
|
@ -2081,7 +2082,7 @@ void BindingsGenerator::_default_argument_from_variant(const Variant &p_val, Arg
|
||||||
r_iarg.default_argument = bool(p_val) ? "true" : "false";
|
r_iarg.default_argument = bool(p_val) ? "true" : "false";
|
||||||
break;
|
break;
|
||||||
case Variant::INT:
|
case Variant::INT:
|
||||||
if (r_iarg.type != name_cache.type_int) {
|
if (r_iarg.type.cname != name_cache.type_int) {
|
||||||
r_iarg.default_argument = "(%s)" + r_iarg.default_argument;
|
r_iarg.default_argument = "(%s)" + r_iarg.default_argument;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -2142,7 +2143,7 @@ void BindingsGenerator::_default_argument_from_variant(const Variant &p_val, Arg
|
||||||
default: {}
|
default: {}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (r_iarg.def_param_mode == ArgumentInterface::CONSTANT && r_iarg.type == name_cache.type_Variant && r_iarg.default_argument != "null")
|
if (r_iarg.def_param_mode == ArgumentInterface::CONSTANT && r_iarg.type.cname == name_cache.type_Variant && r_iarg.default_argument != "null")
|
||||||
r_iarg.def_param_mode = ArgumentInterface::NULLABLE_REF;
|
r_iarg.def_param_mode = ArgumentInterface::NULLABLE_REF;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2161,7 +2162,7 @@ void BindingsGenerator::_populate_builtin_type_interfaces() {
|
||||||
itype.c_arg_in = "&%s_in"; \
|
itype.c_arg_in = "&%s_in"; \
|
||||||
itype.c_type_in = m_type_in; \
|
itype.c_type_in = m_type_in; \
|
||||||
itype.cs_in = "ref %s"; \
|
itype.cs_in = "ref %s"; \
|
||||||
itype.cs_out = "return (" #m_type ")%0;"; \
|
itype.cs_out = "return (%1)%0;"; \
|
||||||
itype.im_type_out = "object"; \
|
itype.im_type_out = "object"; \
|
||||||
builtin_types.insert(itype.cname, itype); \
|
builtin_types.insert(itype.cname, itype); \
|
||||||
}
|
}
|
||||||
|
@ -2256,7 +2257,7 @@ void BindingsGenerator::_populate_builtin_type_interfaces() {
|
||||||
itype.c_type_out = itype.c_type + "*";
|
itype.c_type_out = itype.c_type + "*";
|
||||||
itype.cs_type = itype.proxy_name;
|
itype.cs_type = itype.proxy_name;
|
||||||
itype.cs_in = "NodePath." CS_SMETHOD_GETINSTANCE "(%0)";
|
itype.cs_in = "NodePath." CS_SMETHOD_GETINSTANCE "(%0)";
|
||||||
itype.cs_out = "return new NodePath(%0);";
|
itype.cs_out = "return new %1(%0);";
|
||||||
itype.im_type_in = "IntPtr";
|
itype.im_type_in = "IntPtr";
|
||||||
itype.im_type_out = "IntPtr";
|
itype.im_type_out = "IntPtr";
|
||||||
_populate_builtin_type(itype, Variant::NODE_PATH);
|
_populate_builtin_type(itype, Variant::NODE_PATH);
|
||||||
|
@ -2279,7 +2280,7 @@ void BindingsGenerator::_populate_builtin_type_interfaces() {
|
||||||
itype.c_type_out = itype.c_type + "*";
|
itype.c_type_out = itype.c_type + "*";
|
||||||
itype.cs_type = itype.proxy_name;
|
itype.cs_type = itype.proxy_name;
|
||||||
itype.cs_in = "RID." CS_SMETHOD_GETINSTANCE "(%0)";
|
itype.cs_in = "RID." CS_SMETHOD_GETINSTANCE "(%0)";
|
||||||
itype.cs_out = "return new RID(%0);";
|
itype.cs_out = "return new %1(%0);";
|
||||||
itype.im_type_in = "IntPtr";
|
itype.im_type_in = "IntPtr";
|
||||||
itype.im_type_out = "IntPtr";
|
itype.im_type_out = "IntPtr";
|
||||||
_populate_builtin_type(itype, Variant::_RID);
|
_populate_builtin_type(itype, Variant::_RID);
|
||||||
|
@ -2408,11 +2409,11 @@ void BindingsGenerator::_populate_builtin_type(TypeInterface &r_itype, Variant::
|
||||||
iarg.name = pi.name;
|
iarg.name = pi.name;
|
||||||
|
|
||||||
if (pi.type == Variant::NIL)
|
if (pi.type == Variant::NIL)
|
||||||
iarg.type = name_cache.type_Variant;
|
iarg.type.cname = name_cache.type_Variant;
|
||||||
else
|
else
|
||||||
iarg.type = Variant::get_type_name(pi.type);
|
iarg.type.cname = Variant::get_type_name(pi.type);
|
||||||
|
|
||||||
if (!r_itype.requires_collections && iarg.type == name_cache.type_Dictionary)
|
if (!r_itype.requires_collections && iarg.type.cname == name_cache.type_Dictionary)
|
||||||
r_itype.requires_collections = true;
|
r_itype.requires_collections = true;
|
||||||
|
|
||||||
if ((mi.default_arguments.size() - mi.arguments.size() + i) >= 0)
|
if ((mi.default_arguments.size() - mi.arguments.size() + i) >= 0)
|
||||||
|
@ -2423,12 +2424,12 @@ void BindingsGenerator::_populate_builtin_type(TypeInterface &r_itype, Variant::
|
||||||
|
|
||||||
if (mi.return_val.type == Variant::NIL) {
|
if (mi.return_val.type == Variant::NIL) {
|
||||||
if (mi.return_val.name != "")
|
if (mi.return_val.name != "")
|
||||||
imethod.return_type = name_cache.type_Variant;
|
imethod.return_type.cname = name_cache.type_Variant;
|
||||||
} else {
|
} else {
|
||||||
imethod.return_type = Variant::get_type_name(mi.return_val.type);
|
imethod.return_type.cname = Variant::get_type_name(mi.return_val.type);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!r_itype.requires_collections && imethod.return_type == name_cache.type_Dictionary)
|
if (!r_itype.requires_collections && imethod.return_type.cname == name_cache.type_Dictionary)
|
||||||
r_itype.requires_collections = true;
|
r_itype.requires_collections = true;
|
||||||
|
|
||||||
if (r_itype.class_doc) {
|
if (r_itype.class_doc) {
|
||||||
|
@ -2494,13 +2495,11 @@ void BindingsGenerator::_populate_global_constants() {
|
||||||
EnumInterface &ienum = E->get();
|
EnumInterface &ienum = E->get();
|
||||||
|
|
||||||
TypeInterface enum_itype;
|
TypeInterface enum_itype;
|
||||||
enum_itype = TypeInterface::create_value_type(ienum.cname);
|
enum_itype.is_enum = true;
|
||||||
enum_itype.c_arg_in = "&%s";
|
enum_itype.name = ienum.cname.operator String();
|
||||||
enum_itype.c_type = "int";
|
enum_itype.cname = ienum.cname;
|
||||||
enum_itype.c_type_in = "int";
|
enum_itype.proxy_name = enum_itype.name;
|
||||||
enum_itype.c_type_out = "int";
|
TypeInterface::postsetup_enum_type(enum_itype);
|
||||||
enum_itype.im_type_in = enum_itype.name;
|
|
||||||
enum_itype.im_type_out = enum_itype.name;
|
|
||||||
enum_types.insert(enum_itype.cname, enum_itype);
|
enum_types.insert(enum_itype.cname, enum_itype);
|
||||||
|
|
||||||
ienum.prefix = _determine_enum_prefix(ienum);
|
ienum.prefix = _determine_enum_prefix(ienum);
|
||||||
|
@ -2521,15 +2520,13 @@ void BindingsGenerator::_populate_global_constants() {
|
||||||
hardcoded_enums.push_back("Vector3.Axis");
|
hardcoded_enums.push_back("Vector3.Axis");
|
||||||
for (List<StringName>::Element *E = hardcoded_enums.front(); E; E = E->next()) {
|
for (List<StringName>::Element *E = hardcoded_enums.front(); E; E = E->next()) {
|
||||||
// These enums are not generated and must be written manually (e.g.: Vector3.Axis)
|
// These enums are not generated and must be written manually (e.g.: Vector3.Axis)
|
||||||
// Here, we are assuming core types do not begin with underscore
|
// Here, we assume core types do not begin with underscore
|
||||||
TypeInterface enum_itype;
|
TypeInterface enum_itype;
|
||||||
enum_itype = TypeInterface::create_value_type(E->get());
|
enum_itype.is_enum = true;
|
||||||
enum_itype.c_arg_in = "&%s";
|
enum_itype.name = E->get().operator String();
|
||||||
enum_itype.c_type = "int";
|
enum_itype.cname = E->get();
|
||||||
enum_itype.c_type_in = "int";
|
enum_itype.proxy_name = enum_itype.name;
|
||||||
enum_itype.c_type_out = "int";
|
TypeInterface::postsetup_enum_type(enum_itype);
|
||||||
enum_itype.im_type_in = enum_itype.name;
|
|
||||||
enum_itype.im_type_out = enum_itype.name;
|
|
||||||
enum_types.insert(enum_itype.cname, enum_itype);
|
enum_types.insert(enum_itype.cname, enum_itype);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,6 +81,15 @@ class BindingsGenerator {
|
||||||
const DocData::PropertyDoc *prop_doc;
|
const DocData::PropertyDoc *prop_doc;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct TypeReference {
|
||||||
|
StringName cname;
|
||||||
|
bool is_enum;
|
||||||
|
|
||||||
|
TypeReference() {
|
||||||
|
is_enum = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
struct ArgumentInterface {
|
struct ArgumentInterface {
|
||||||
enum DefaultParamMode {
|
enum DefaultParamMode {
|
||||||
CONSTANT,
|
CONSTANT,
|
||||||
|
@ -88,7 +97,8 @@ class BindingsGenerator {
|
||||||
NULLABLE_REF
|
NULLABLE_REF
|
||||||
};
|
};
|
||||||
|
|
||||||
StringName type;
|
TypeReference type;
|
||||||
|
|
||||||
String name;
|
String name;
|
||||||
String default_argument;
|
String default_argument;
|
||||||
DefaultParamMode def_param_mode;
|
DefaultParamMode def_param_mode;
|
||||||
|
@ -110,7 +120,7 @@ class BindingsGenerator {
|
||||||
/**
|
/**
|
||||||
* [TypeInterface::name] of the return type
|
* [TypeInterface::name] of the return type
|
||||||
*/
|
*/
|
||||||
StringName return_type;
|
TypeReference return_type;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determines if the method has a variable number of arguments (VarArg)
|
* Determines if the method has a variable number of arguments (VarArg)
|
||||||
|
@ -146,7 +156,7 @@ class BindingsGenerator {
|
||||||
}
|
}
|
||||||
|
|
||||||
MethodInterface() {
|
MethodInterface() {
|
||||||
return_type = BindingsGenerator::get_singleton()->name_cache.type_void;
|
return_type.cname = BindingsGenerator::get_singleton()->name_cache.type_void;
|
||||||
is_vararg = false;
|
is_vararg = false;
|
||||||
is_virtual = false;
|
is_virtual = false;
|
||||||
requires_object_call = false;
|
requires_object_call = false;
|
||||||
|
@ -175,6 +185,7 @@ class BindingsGenerator {
|
||||||
|
|
||||||
ClassDB::APIType api_type;
|
ClassDB::APIType api_type;
|
||||||
|
|
||||||
|
bool is_enum;
|
||||||
bool is_object_type;
|
bool is_object_type;
|
||||||
bool is_singleton;
|
bool is_singleton;
|
||||||
bool is_reference;
|
bool is_reference;
|
||||||
|
@ -276,7 +287,9 @@ class BindingsGenerator {
|
||||||
* One or more statements that determine how a variable of this type is returned from a method.
|
* One or more statements that determine how a variable of this type is returned from a method.
|
||||||
* It must contain the return statement(s).
|
* It must contain the return statement(s).
|
||||||
* Formatting elements:
|
* Formatting elements:
|
||||||
* %0 or %s: name of the variable to be returned
|
* %0: internal method call statement
|
||||||
|
* %1: [cs_type] of the return type
|
||||||
|
* %2: [im_type_out] of the return type
|
||||||
*/
|
*/
|
||||||
String cs_out;
|
String cs_out;
|
||||||
|
|
||||||
|
@ -293,8 +306,6 @@ class BindingsGenerator {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Type used for the return type of internal call methods.
|
* Type used for the return type of internal call methods.
|
||||||
* If [cs_out] is not empty and the method return type is not void,
|
|
||||||
* it is also used for the type of the return variable.
|
|
||||||
*/
|
*/
|
||||||
String im_type_out;
|
String im_type_out;
|
||||||
|
|
||||||
|
@ -379,10 +390,24 @@ class BindingsGenerator {
|
||||||
r_itype.im_type_out = r_itype.proxy_name;
|
r_itype.im_type_out = r_itype.proxy_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void postsetup_enum_type(TypeInterface &r_enum_itype) {
|
||||||
|
r_enum_itype.c_arg_in = "&%s";
|
||||||
|
r_enum_itype.c_type = "int";
|
||||||
|
r_enum_itype.c_type_in = "int";
|
||||||
|
r_enum_itype.c_type_out = "int";
|
||||||
|
r_enum_itype.cs_type = r_enum_itype.proxy_name;
|
||||||
|
r_enum_itype.cs_in = "(int)%s";
|
||||||
|
r_enum_itype.cs_out = "return (%1)%0;";
|
||||||
|
r_enum_itype.im_type_in = "int";
|
||||||
|
r_enum_itype.im_type_out = "int";
|
||||||
|
r_enum_itype.class_doc = &EditorHelp::get_doc_data()->class_list[r_enum_itype.proxy_name];
|
||||||
|
}
|
||||||
|
|
||||||
TypeInterface() {
|
TypeInterface() {
|
||||||
|
|
||||||
api_type = ClassDB::API_NONE;
|
api_type = ClassDB::API_NONE;
|
||||||
|
|
||||||
|
is_enum = false;
|
||||||
is_object_type = false;
|
is_object_type = false;
|
||||||
is_singleton = false;
|
is_singleton = false;
|
||||||
is_reference = false;
|
is_reference = false;
|
||||||
|
@ -492,6 +517,8 @@ class BindingsGenerator {
|
||||||
return "Ref";
|
return "Ref";
|
||||||
else if (p_type.is_object_type)
|
else if (p_type.is_object_type)
|
||||||
return "Obj";
|
return "Obj";
|
||||||
|
else if (p_type.is_enum)
|
||||||
|
return "int";
|
||||||
|
|
||||||
return p_type.name;
|
return p_type.name;
|
||||||
}
|
}
|
||||||
|
@ -501,8 +528,8 @@ class BindingsGenerator {
|
||||||
void _generate_header_icalls();
|
void _generate_header_icalls();
|
||||||
void _generate_method_icalls(const TypeInterface &p_itype);
|
void _generate_method_icalls(const TypeInterface &p_itype);
|
||||||
|
|
||||||
const TypeInterface *_get_type_by_name_or_null(const StringName &p_cname);
|
const TypeInterface *_get_type_or_null(const TypeReference &p_typeref);
|
||||||
const TypeInterface *_get_type_by_name_or_placeholder(const StringName &p_cname);
|
const TypeInterface *_get_type_or_placeholder(const TypeReference &p_typeref);
|
||||||
|
|
||||||
void _default_argument_from_variant(const Variant &p_val, ArgumentInterface &r_iarg);
|
void _default_argument_from_variant(const Variant &p_val, ArgumentInterface &r_iarg);
|
||||||
void _populate_builtin_type(TypeInterface &r_itype, Variant::Type vtype);
|
void _populate_builtin_type(TypeInterface &r_itype, Variant::Type vtype);
|
||||||
|
|
Loading…
Reference in New Issue