Merge pull request #18494 from neikeq/v
Mono: BindingsGenerator enum fixes
This commit is contained in:
commit
d0183effe0
|
@ -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