summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgnacio Etcheverry <neikeq@users.noreply.github.com>2018-10-18 20:29:59 +0200
committerGitHub <noreply@github.com>2018-10-18 20:29:59 +0200
commitc8b7e9e5b72c26c8d421508b63c4665be1c51060 (patch)
treed5df0b3c0085702d924eb7a95ebb363331e76d1b
parentad47ec3952c34e2cfb64b8d65f1ed5614c73222f (diff)
parent2adef1e52fc323b00a02cd08154c83ebfffa3562 (diff)
Merge pull request #23119 from neikeq/issue-18796
Fix prefix erasing for the generated C# enum constants
-rw-r--r--modules/mono/editor/bindings_generator.cpp144
-rw-r--r--modules/mono/editor/bindings_generator.h8
2 files changed, 89 insertions, 63 deletions
diff --git a/modules/mono/editor/bindings_generator.cpp b/modules/mono/editor/bindings_generator.cpp
index 41666bc3e9..710682d3aa 100644
--- a/modules/mono/editor/bindings_generator.cpp
+++ b/modules/mono/editor/bindings_generator.cpp
@@ -97,7 +97,7 @@
#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 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";
@@ -173,23 +173,74 @@ static String snake_to_camel_case(const String &p_identifier, bool p_input_is_up
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());
- const List<ConstantInterface>::Element *front = p_ienum.constants.front();
- int candidate_len = front->get().name.length();
+ const ConstantInterface &front_iconstant = p_ienum.constants.front()->get();
+ 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()) {
- int j = 0;
- for (j = 0; j < candidate_len && j < E->get().name.length(); j++) {
- if (front->get().name[j] != E->get().name[j])
- break;
+ if (candidate_len == 0)
+ return 0;
+
+ for (const List<ConstantInterface>::Element *E = p_ienum.constants.front()->next(); E; E = E->next()) {
+ 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) {
@@ -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(iconstant.name);
+ p_output.push_back(iconstant.proxy_name);
p_output.push_back(" = ");
p_output.push_back(itos(iconstant.value));
p_output.push_back(";");
@@ -334,25 +385,8 @@ void BindingsGenerator::_generate_global_constants(List<String> &p_output) {
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(constant_name);
+ p_output.push_back(iconstant.proxy_name);
p_output.push_back(" = ");
p_output.push_back(itos(iconstant.value));
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(iconstant.name);
+ output.push_back(iconstant.proxy_name);
output.push_back(" = ");
output.push_back(itos(iconstant.value));
output.push_back(";");
@@ -760,25 +794,8 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str
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(constant_name);
+ output.push_back(iconstant.proxy_name);
output.push_back(" = ");
output.push_back(itos(iconstant.value));
output.push_back(E != ienum.constants.back() ? ",\n" : "\n");
@@ -1846,11 +1863,13 @@ void BindingsGenerator::_populate_object_type_interfaces() {
EnumInterface ienum(enum_proxy_cname);
const List<StringName> &constants = enum_map.get(*k);
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);
- 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;
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.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);
@@ -1879,10 +1900,11 @@ void BindingsGenerator::_populate_object_type_interfaces() {
}
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);
- 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;
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);
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;
if (enum_name != StringName()) {
@@ -2293,16 +2315,18 @@ void BindingsGenerator::_populate_global_constants() {
TypeInterface::postsetup_enum_type(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.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");
}
- ienum.prefix = "Err";
+ prefix_length = 1; // 'ERR_'
}
+
+ _apply_prefix_to_enum_constants(ienum, prefix_length);
}
}
diff --git a/modules/mono/editor/bindings_generator.h b/modules/mono/editor/bindings_generator.h
index 7ae52e180f..38cf99c294 100644
--- a/modules/mono/editor/bindings_generator.h
+++ b/modules/mono/editor/bindings_generator.h
@@ -43,20 +43,21 @@ class BindingsGenerator {
struct ConstantInterface {
String name;
+ String proxy_name;
int value;
const DocData::ConstantDoc *const_doc;
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;
+ proxy_name = p_proxy_name;
value = p_value;
}
};
struct EnumInterface {
StringName cname;
- String prefix;
List<ConstantInterface> constants;
_FORCE_INLINE_ bool operator==(const EnumInterface &p_ienum) const {
@@ -520,7 +521,8 @@ class BindingsGenerator {
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);