mirror of https://github.com/godotengine/godot
Fix prefix erasing for the generated C# enum constants
This commit is contained in:
parent
b550f93cfd
commit
2adef1e52f
|
|
@ -97,7 +97,7 @@
|
||||||
#define C_METHOD_MONOARRAY_TO(m_type) C_NS_MONOMARSHAL "::mono_array_to_" #m_type
|
#define C_METHOD_MONOARRAY_TO(m_type) C_NS_MONOMARSHAL "::mono_array_to_" #m_type
|
||||||
#define C_METHOD_MONOARRAY_FROM(m_type) C_NS_MONOMARSHAL "::" #m_type "_to_mono_array"
|
#define C_METHOD_MONOARRAY_FROM(m_type) C_NS_MONOMARSHAL "::" #m_type "_to_mono_array"
|
||||||
|
|
||||||
#define BINDINGS_GENERATOR_VERSION UINT32_C(4)
|
#define BINDINGS_GENERATOR_VERSION UINT32_C(5)
|
||||||
|
|
||||||
const char *BindingsGenerator::TypeInterface::DEFAULT_VARARG_C_IN = "\t%0 %1_in = %1;\n";
|
const char *BindingsGenerator::TypeInterface::DEFAULT_VARARG_C_IN = "\t%0 %1_in = %1;\n";
|
||||||
|
|
||||||
|
|
@ -173,23 +173,74 @@ static String snake_to_camel_case(const String &p_identifier, bool p_input_is_up
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
String BindingsGenerator::_determine_enum_prefix(const EnumInterface &p_ienum) {
|
int BindingsGenerator::_determine_enum_prefix(const EnumInterface &p_ienum) {
|
||||||
|
|
||||||
CRASH_COND(p_ienum.constants.empty());
|
CRASH_COND(p_ienum.constants.empty());
|
||||||
|
|
||||||
const List<ConstantInterface>::Element *front = p_ienum.constants.front();
|
const ConstantInterface &front_iconstant = p_ienum.constants.front()->get();
|
||||||
int candidate_len = front->get().name.length();
|
Vector<String> front_parts = front_iconstant.name.split("_", /* p_allow_empty: */ true);
|
||||||
|
int candidate_len = front_parts.size() - 1;
|
||||||
|
|
||||||
for (const List<ConstantInterface>::Element *E = front->next(); E; E = E->next()) {
|
if (candidate_len == 0)
|
||||||
int j = 0;
|
return 0;
|
||||||
for (j = 0; j < candidate_len && j < E->get().name.length(); j++) {
|
|
||||||
if (front->get().name[j] != E->get().name[j])
|
for (const List<ConstantInterface>::Element *E = p_ienum.constants.front()->next(); E; E = E->next()) {
|
||||||
break;
|
const ConstantInterface &iconstant = E->get();
|
||||||
|
|
||||||
|
Vector<String> parts = iconstant.name.split("_", /* p_allow_empty: */ true);
|
||||||
|
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < candidate_len && i < parts.size(); i++) {
|
||||||
|
if (front_parts[i] != parts[i]) {
|
||||||
|
// HARDCODED: Some Flag enums have the prefix 'FLAG_' for everything except 'FLAGS_DEFAULT' (same for 'METHOD_FLAG_' and'METHOD_FLAGS_DEFAULT').
|
||||||
|
bool hardcoded_exc = (i == candidate_len - 1 && ((front_parts[i] == "FLAGS" && parts[i] == "FLAG") || (front_parts[i] == "FLAG" && parts[i] == "FLAGS")));
|
||||||
|
if (!hardcoded_exc)
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
candidate_len = j;
|
candidate_len = i;
|
||||||
|
|
||||||
|
if (candidate_len == 0)
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return front->get().name.substr(0, candidate_len);
|
return candidate_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BindingsGenerator::_apply_prefix_to_enum_constants(BindingsGenerator::EnumInterface &p_ienum, int p_prefix_length) {
|
||||||
|
|
||||||
|
if (p_prefix_length > 0) {
|
||||||
|
for (List<ConstantInterface>::Element *E = p_ienum.constants.front(); E; E = E->next()) {
|
||||||
|
int curr_prefix_length = p_prefix_length;
|
||||||
|
|
||||||
|
ConstantInterface &curr_const = E->get();
|
||||||
|
|
||||||
|
String constant_name = curr_const.name;
|
||||||
|
|
||||||
|
Vector<String> parts = constant_name.split("_", /* p_allow_empty: */ true);
|
||||||
|
|
||||||
|
if (parts.size() <= curr_prefix_length)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (parts[curr_prefix_length][0] >= '0' && parts[curr_prefix_length][0] <= '9') {
|
||||||
|
// The name of enum constants may begin with a numeric digit when strip from the enum prefix,
|
||||||
|
// so we make the prefix for this constant one word shorter in those cases.
|
||||||
|
for (curr_prefix_length = curr_prefix_length - 1; curr_prefix_length > 0; curr_prefix_length--) {
|
||||||
|
if (parts[curr_prefix_length][0] < '0' || parts[curr_prefix_length][0] > '9')
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
constant_name = "";
|
||||||
|
for (int i = curr_prefix_length; i < parts.size(); i++) {
|
||||||
|
if (i > curr_prefix_length)
|
||||||
|
constant_name += "_";
|
||||||
|
constant_name += parts[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
curr_const.proxy_name = snake_to_pascal_case(constant_name, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void BindingsGenerator::_generate_method_icalls(const TypeInterface &p_itype) {
|
void BindingsGenerator::_generate_method_icalls(const TypeInterface &p_itype) {
|
||||||
|
|
@ -272,7 +323,7 @@ void BindingsGenerator::_generate_global_constants(List<String> &p_output) {
|
||||||
}
|
}
|
||||||
|
|
||||||
p_output.push_back(MEMBER_BEGIN "public const int ");
|
p_output.push_back(MEMBER_BEGIN "public const int ");
|
||||||
p_output.push_back(iconstant.name);
|
p_output.push_back(iconstant.proxy_name);
|
||||||
p_output.push_back(" = ");
|
p_output.push_back(" = ");
|
||||||
p_output.push_back(itos(iconstant.value));
|
p_output.push_back(itos(iconstant.value));
|
||||||
p_output.push_back(";");
|
p_output.push_back(";");
|
||||||
|
|
@ -334,25 +385,8 @@ void BindingsGenerator::_generate_global_constants(List<String> &p_output) {
|
||||||
p_output.push_back(INDENT2 "/// </summary>\n");
|
p_output.push_back(INDENT2 "/// </summary>\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
String constant_name = iconstant.name;
|
|
||||||
|
|
||||||
if (!ienum.prefix.empty() && constant_name.begins_with(ienum.prefix)) {
|
|
||||||
constant_name = constant_name.substr(ienum.prefix.length(), constant_name.length());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (constant_name[0] >= '0' && constant_name[0] <= '9') {
|
|
||||||
// The name of enum constants may begin with a numeric digit when strip from the enum prefix,
|
|
||||||
// so we make the prefix one word shorter in those cases.
|
|
||||||
int i = 0;
|
|
||||||
for (i = ienum.prefix.length() - 1; i >= 0; i--) {
|
|
||||||
if (ienum.prefix[i] >= 'A' && ienum.prefix[i] <= 'Z')
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
constant_name = ienum.prefix.substr(i, ienum.prefix.length()) + constant_name;
|
|
||||||
}
|
|
||||||
|
|
||||||
p_output.push_back(INDENT2);
|
p_output.push_back(INDENT2);
|
||||||
p_output.push_back(constant_name);
|
p_output.push_back(iconstant.proxy_name);
|
||||||
p_output.push_back(" = ");
|
p_output.push_back(" = ");
|
||||||
p_output.push_back(itos(iconstant.value));
|
p_output.push_back(itos(iconstant.value));
|
||||||
p_output.push_back(E != ienum.constants.back() ? ",\n" : "\n");
|
p_output.push_back(E != ienum.constants.back() ? ",\n" : "\n");
|
||||||
|
|
@ -720,7 +754,7 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str
|
||||||
}
|
}
|
||||||
|
|
||||||
output.push_back(MEMBER_BEGIN "public const int ");
|
output.push_back(MEMBER_BEGIN "public const int ");
|
||||||
output.push_back(iconstant.name);
|
output.push_back(iconstant.proxy_name);
|
||||||
output.push_back(" = ");
|
output.push_back(" = ");
|
||||||
output.push_back(itos(iconstant.value));
|
output.push_back(itos(iconstant.value));
|
||||||
output.push_back(";");
|
output.push_back(";");
|
||||||
|
|
@ -760,25 +794,8 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str
|
||||||
output.push_back(INDENT3 "/// </summary>\n");
|
output.push_back(INDENT3 "/// </summary>\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
String constant_name = iconstant.name;
|
|
||||||
|
|
||||||
if (!ienum.prefix.empty() && constant_name.begins_with(ienum.prefix)) {
|
|
||||||
constant_name = constant_name.substr(ienum.prefix.length(), constant_name.length());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (constant_name[0] >= '0' && constant_name[0] <= '9') {
|
|
||||||
// The name of enum constants may begin with a numeric digit when strip from the enum prefix,
|
|
||||||
// so we make the prefix one word shorter in those cases.
|
|
||||||
int i = 0;
|
|
||||||
for (i = ienum.prefix.length() - 1; i >= 0; i--) {
|
|
||||||
if (ienum.prefix[i] >= 'A' && ienum.prefix[i] <= 'Z')
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
constant_name = ienum.prefix.substr(i, ienum.prefix.length()) + constant_name;
|
|
||||||
}
|
|
||||||
|
|
||||||
output.push_back(INDENT3);
|
output.push_back(INDENT3);
|
||||||
output.push_back(constant_name);
|
output.push_back(iconstant.proxy_name);
|
||||||
output.push_back(" = ");
|
output.push_back(" = ");
|
||||||
output.push_back(itos(iconstant.value));
|
output.push_back(itos(iconstant.value));
|
||||||
output.push_back(E != ienum.constants.back() ? ",\n" : "\n");
|
output.push_back(E != ienum.constants.back() ? ",\n" : "\n");
|
||||||
|
|
@ -1846,11 +1863,13 @@ void BindingsGenerator::_populate_object_type_interfaces() {
|
||||||
EnumInterface ienum(enum_proxy_cname);
|
EnumInterface ienum(enum_proxy_cname);
|
||||||
const List<StringName> &constants = enum_map.get(*k);
|
const List<StringName> &constants = enum_map.get(*k);
|
||||||
for (const List<StringName>::Element *E = constants.front(); E; E = E->next()) {
|
for (const List<StringName>::Element *E = constants.front(); E; E = E->next()) {
|
||||||
int *value = class_info->constant_map.getptr(E->get());
|
const StringName &constant_cname = E->get();
|
||||||
|
String constant_name = constant_cname.operator String();
|
||||||
|
int *value = class_info->constant_map.getptr(constant_cname);
|
||||||
ERR_FAIL_NULL(value);
|
ERR_FAIL_NULL(value);
|
||||||
constant_list.erase(E->get().operator String());
|
constant_list.erase(constant_name);
|
||||||
|
|
||||||
ConstantInterface iconstant(snake_to_pascal_case(E->get(), true), *value);
|
ConstantInterface iconstant(constant_name, snake_to_pascal_case(constant_name, true), *value);
|
||||||
|
|
||||||
iconstant.const_doc = NULL;
|
iconstant.const_doc = NULL;
|
||||||
for (int i = 0; i < itype.class_doc->constants.size(); i++) {
|
for (int i = 0; i < itype.class_doc->constants.size(); i++) {
|
||||||
|
|
@ -1865,7 +1884,9 @@ void BindingsGenerator::_populate_object_type_interfaces() {
|
||||||
ienum.constants.push_back(iconstant);
|
ienum.constants.push_back(iconstant);
|
||||||
}
|
}
|
||||||
|
|
||||||
ienum.prefix = _determine_enum_prefix(ienum);
|
int prefix_length = _determine_enum_prefix(ienum);
|
||||||
|
|
||||||
|
_apply_prefix_to_enum_constants(ienum, prefix_length);
|
||||||
|
|
||||||
itype.enums.push_back(ienum);
|
itype.enums.push_back(ienum);
|
||||||
|
|
||||||
|
|
@ -1879,10 +1900,11 @@ void BindingsGenerator::_populate_object_type_interfaces() {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const List<String>::Element *E = constant_list.front(); E; E = E->next()) {
|
for (const List<String>::Element *E = constant_list.front(); E; E = E->next()) {
|
||||||
int *value = class_info->constant_map.getptr(E->get());
|
const String &constant_name = E->get();
|
||||||
|
int *value = class_info->constant_map.getptr(StringName(E->get()));
|
||||||
ERR_FAIL_NULL(value);
|
ERR_FAIL_NULL(value);
|
||||||
|
|
||||||
ConstantInterface iconstant(snake_to_pascal_case(E->get(), true), *value);
|
ConstantInterface iconstant(constant_name, snake_to_pascal_case(constant_name, true), *value);
|
||||||
|
|
||||||
iconstant.const_doc = NULL;
|
iconstant.const_doc = NULL;
|
||||||
for (int i = 0; i < itype.class_doc->constants.size(); i++) {
|
for (int i = 0; i < itype.class_doc->constants.size(); i++) {
|
||||||
|
|
@ -2265,7 +2287,7 @@ void BindingsGenerator::_populate_global_constants() {
|
||||||
int constant_value = GlobalConstants::get_global_constant_value(i);
|
int constant_value = GlobalConstants::get_global_constant_value(i);
|
||||||
StringName enum_name = GlobalConstants::get_global_constant_enum(i);
|
StringName enum_name = GlobalConstants::get_global_constant_enum(i);
|
||||||
|
|
||||||
ConstantInterface iconstant(snake_to_pascal_case(constant_name, true), constant_value);
|
ConstantInterface iconstant(constant_name, snake_to_pascal_case(constant_name, true), constant_value);
|
||||||
iconstant.const_doc = const_doc;
|
iconstant.const_doc = const_doc;
|
||||||
|
|
||||||
if (enum_name != StringName()) {
|
if (enum_name != StringName()) {
|
||||||
|
|
@ -2293,16 +2315,18 @@ void BindingsGenerator::_populate_global_constants() {
|
||||||
TypeInterface::postsetup_enum_type(enum_itype);
|
TypeInterface::postsetup_enum_type(enum_itype);
|
||||||
enum_types.insert(enum_itype.cname, enum_itype);
|
enum_types.insert(enum_itype.cname, enum_itype);
|
||||||
|
|
||||||
ienum.prefix = _determine_enum_prefix(ienum);
|
int prefix_length = _determine_enum_prefix(ienum);
|
||||||
|
|
||||||
// HARDCODED
|
// HARDCODED: The Error enum have the prefix 'ERR_' for everything except 'OK' and 'FAILED'.
|
||||||
if (ienum.cname == name_cache.enum_Error) {
|
if (ienum.cname == name_cache.enum_Error) {
|
||||||
if (!ienum.prefix.empty()) { // Just in case it ever changes
|
if (prefix_length > 0) { // Just in case it ever changes
|
||||||
ERR_PRINTS("Prefix for enum 'Error' is not empty");
|
ERR_PRINTS("Prefix for enum 'Error' is not empty");
|
||||||
}
|
}
|
||||||
|
|
||||||
ienum.prefix = "Err";
|
prefix_length = 1; // 'ERR_'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_apply_prefix_to_enum_constants(ienum, prefix_length);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -43,20 +43,21 @@ class BindingsGenerator {
|
||||||
|
|
||||||
struct ConstantInterface {
|
struct ConstantInterface {
|
||||||
String name;
|
String name;
|
||||||
|
String proxy_name;
|
||||||
int value;
|
int value;
|
||||||
const DocData::ConstantDoc *const_doc;
|
const DocData::ConstantDoc *const_doc;
|
||||||
|
|
||||||
ConstantInterface() {}
|
ConstantInterface() {}
|
||||||
|
|
||||||
ConstantInterface(const String &p_name, int p_value) {
|
ConstantInterface(const String &p_name, const String &p_proxy_name, int p_value) {
|
||||||
name = p_name;
|
name = p_name;
|
||||||
|
proxy_name = p_proxy_name;
|
||||||
value = p_value;
|
value = p_value;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct EnumInterface {
|
struct EnumInterface {
|
||||||
StringName cname;
|
StringName cname;
|
||||||
String prefix;
|
|
||||||
List<ConstantInterface> constants;
|
List<ConstantInterface> constants;
|
||||||
|
|
||||||
_FORCE_INLINE_ bool operator==(const EnumInterface &p_ienum) const {
|
_FORCE_INLINE_ bool operator==(const EnumInterface &p_ienum) const {
|
||||||
|
|
@ -520,7 +521,8 @@ class BindingsGenerator {
|
||||||
return p_type.name;
|
return p_type.name;
|
||||||
}
|
}
|
||||||
|
|
||||||
String _determine_enum_prefix(const EnumInterface &p_ienum);
|
int _determine_enum_prefix(const EnumInterface &p_ienum);
|
||||||
|
void _apply_prefix_to_enum_constants(EnumInterface &p_ienum, int p_prefix_length);
|
||||||
|
|
||||||
void _generate_method_icalls(const TypeInterface &p_itype);
|
void _generate_method_icalls(const TypeInterface &p_itype);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue