@@ -18,12 +18,12 @@ struct CXXMethodBridging {
1818 if (nameIsBlacklist ())
1919 return Kind::unknown;
2020
21- // this should be handled as snake case. See: rdar://89453010
21+ // This should be handled as snake case. See: rdar://89453010
2222 // case. In the future we could
2323 // import these too, though.
2424 auto nameKind = classifyNameKind ();
2525 if (nameKind != NameKind::title && nameKind != NameKind::camel &&
26- nameKind != NameKind::lower)
26+ nameKind != NameKind::lower && nameKind != NameKind::snake )
2727 return Kind::unknown;
2828
2929 if (getClangName ().startswith_insensitive (" set" )) {
@@ -62,16 +62,18 @@ struct CXXMethodBridging {
6262 }
6363
6464 NameKind classifyNameKind () {
65- bool allLower = llvm::all_of (getClangName (), islower);
65+ bool hasUpper = llvm::any_of (
66+ getClangName (), [](unsigned char ch) { return std::isupper (ch); });
6667
67- if (getClangName ().empty ())
68+ if (getClangName ().empty ()) {
6869 return NameKind::unknown;
70+ }
6971
70- if (getClangName ().contains (' _' ))
71- return allLower ? NameKind::snake : NameKind::unknown;
72-
73- if (allLower)
72+ if (getClangName ().contains (' _' )) {
73+ return hasUpper ? NameKind::unknown : NameKind::snake;
74+ } else if (!hasUpper) {
7475 return NameKind::lower;
76+ }
7577
7678 return islower (getClangName ().front ()) ? NameKind::camel : NameKind::title;
7779 }
@@ -83,7 +85,7 @@ struct CXXMethodBridging {
8385 return method->getName ();
8486 }
8587
86- // this should be handled as snake case. See: rdar://89453010
88+ // This should be handled as snake case. See: rdar://89453010
8789 std::string importNameAsCamelCaseName () {
8890 std::string output;
8991 auto kind = classify ();
@@ -103,6 +105,24 @@ struct CXXMethodBridging {
103105 // The first character is always lowercase.
104106 output.front () = std::tolower (output.front ());
105107
108+ if (classifyNameKind () == NameKind::snake) {
109+ for (std::size_t i = 0 ; i < output.size (); i++) {
110+ size_t next = i + 1 ;
111+ if (output[i] == ' _' ) {
112+ // If the first or last element is an underscore, remove it.
113+ if (i == 0 || next == output.size ()) {
114+ output.erase (i, 1 );
115+ } else if (next < output.size ()) {
116+ // If the current element is an underscore, capitalize the element
117+ // next to it, and remove the extra element.
118+ output[i] = std::toupper (output[next]);
119+ output.erase (next, 1 );
120+ }
121+ }
122+ }
123+ return output;
124+ }
125+
106126 // We already lowercased the first element, so start at one. Look at the
107127 // current element and the next one. To handle cases like UTF8String, start
108128 // making all the uppercase characters lower, until we see an upper case
0 commit comments