Skip to content

Commit 436847b

Browse files
committed
[cxx-interop] Update CxxMethodBridging with snake_case
1 parent 07e54bf commit 436847b

File tree

9 files changed

+114
-29
lines changed

9 files changed

+114
-29
lines changed

include/swift/AST/DiagnosticsFrontend.def

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,7 @@ ERROR(batch_scan_input_file_corrupted,none,
302302
(StringRef))
303303

304304
ERROR(unknown_platform_name, none,
305-
"unkown platform name %0", (StringRef))
305+
"unknown platform name %0", (StringRef))
306306

307307
ERROR(unknown_swift_module_name, none,
308308
"cannot find Swift module with name %0", (StringRef))

include/swift/ClangImporter/CXXMethodBridging.h

Lines changed: 57 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,70 +8,92 @@
88
#include <string>
99
namespace swift {
1010
struct CXXMethodBridging {
11-
enum class Kind { unkown, getter, setter, subscript };
11+
enum class Kind { unknown, getter, setter, subscript };
1212

13-
enum class NameKind { unkown, snake, lower, camel, title };
13+
enum class NameKind { unknown, snake, lower, camel, title };
1414

1515
CXXMethodBridging(const clang::CXXMethodDecl *method) : method(method) {}
1616

1717
Kind classify() {
1818
if (nameIsBlacklist())
19-
return Kind::unkown;
19+
return Kind::unknown;
2020

2121
// 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)
27-
return Kind::unkown;
26+
nameKind != NameKind::lower && nameKind != NameKind::snake)
27+
return Kind::unknown;
2828

2929
if (getClangName().startswith_insensitive("set")) {
3030
// Setters only have one parameter.
3131
if (method->getNumParams() != 1)
32-
return Kind::unkown;
32+
return Kind::unknown;
3333

3434
// rdar://89453106 (We need to handle imported properties that return a
3535
// reference)
3636
if (method->getParamDecl(0)->getType()->isReferenceType())
37-
return Kind::unkown;
37+
return Kind::unknown;
3838

3939
return Kind::setter;
4040
}
4141

4242
// Getters and subscripts cannot return void.
4343
if (method->getReturnType()->isVoidType())
44-
return Kind::unkown;
44+
return Kind::unknown;
4545

4646
if (getClangName().startswith_insensitive("get")) {
4747
// Getters cannot take arguments.
4848
if (method->getNumParams() != 0)
49-
return Kind::unkown;
49+
return Kind::unknown;
5050

5151
// rdar://89453106 (We need to handle imported properties that return a
5252
// reference)
5353
if (method->getReturnType()->isReferenceType())
54-
return Kind::unkown;
54+
return Kind::unknown;
5555

5656
return Kind::getter;
5757
}
5858

5959
// rdar://89453187 (Add subscripts clarification to CXXMethod Bridging to
6060
// clean up importDecl)
61-
return Kind::unkown;
61+
return Kind::unknown;
6262
}
6363

6464
NameKind classifyNameKind() {
6565
bool allLower = llvm::all_of(getClangName(), islower);
66+
bool hasUpper = false;
6667

67-
if (getClangName().empty())
68-
return NameKind::unkown;
68+
for (std::size_t i = 0; i < getClangName().size(); i++) {
69+
if (std::isupper(getClangName()[i])) {
70+
hasUpper = true;
71+
}
72+
}
6973

70-
if (getClangName().contains('_'))
71-
return allLower ? NameKind::snake : NameKind::unkown;
74+
// if the string is empty
75+
if (getClangName().empty()) {
76+
return NameKind::unknown;
77+
}
7278

73-
if (allLower)
74-
return NameKind::lower;
79+
// if one of the elements is an underscore
80+
if (getClangName().contains('_')) {
81+
if (allLower) {
82+
return NameKind::snake;
83+
} else {
84+
// if there is an underscore and contains an uppercase
85+
if (hasUpper) {
86+
return NameKind::unknown;
87+
} else {
88+
// if there is an underscore, there are no uppercase letters and can
89+
// contain numbers
90+
return NameKind::snake;
91+
}
92+
93+
// final check
94+
return allLower ? NameKind::snake : NameKind::unknown;
95+
}
96+
}
7597

7698
return islower(getClangName().front()) ? NameKind::camel : NameKind::title;
7799
}
@@ -103,6 +125,24 @@ struct CXXMethodBridging {
103125
// The first character is always lowercase.
104126
output.front() = std::tolower(output.front());
105127

128+
if (classifyNameKind() == NameKind::snake) {
129+
for (std::size_t i = 0; i < output.size(); i++) {
130+
size_t next = i + 1;
131+
if (output[i] == '_') {
132+
// if the first element is an underscore, remove it
133+
if (i == 0) {
134+
output.erase(i, 1);
135+
} else {
136+
// if the current element is an underscore, capitalize the element
137+
// next to it, and remove the extra element
138+
output[i] = std::toupper(output[next]);
139+
output.erase(next, 1);
140+
}
141+
}
142+
}
143+
return output;
144+
}
145+
106146
// We already lowercased the first element, so start at one. Look at the
107147
// current element and the next one. To handle cases like UTF8String, start
108148
// making all the uppercase characters lower, until we see an upper case

test/Index/index_generic_params.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ extension Wrapper2.NonGenericWrapped where Wrapper2Param: P1 {
8080
func bar(x: Wrapper2Param.Assoc) {}
8181
}
8282

83-
// MARK: - Test extending an unkown type
83+
// MARK: - Test extending an unknown type
8484

8585
// Check that we don't crash. We don't expect the generic params to show up in the index.
8686
extension MyUnknownType where Wrapper2Param: P1 {

test/Interop/Cxx/ergonomics/Inputs/implicit-computed-properties.h

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,15 +39,15 @@ struct LongNameAllUpper {
3939
};
4040

4141
struct UpperCaseMix {
42-
mutable int value = 42;
43-
int getFoo() const { return value; }
44-
void SetFoo(int v) { value = v; }
42+
mutable int value = 42;
43+
int getFoo() const { return value; }
44+
void SetFoo(int v) { value = v; }
4545
};
4646

4747
struct UpperCaseGetterSetter {
48-
mutable int value = 42;
49-
int GetFoo() const { return value; }
50-
void SetFoo(int v) { value = v; }
48+
mutable int value = 42;
49+
int GetFoo() const { return value; }
50+
void SetFoo(int v) { value = v; }
5151
};
5252

5353
struct GetterOnly {
@@ -191,4 +191,16 @@ class PrivatePropertyWithSameName {
191191
void setValue(int i);
192192
};
193193

194+
struct SnakeCaseGetterSetter {
195+
mutable int value;
196+
int get_foo() const { return value; }
197+
void set_foo(int v) { value = v; }
198+
};
199+
200+
struct SnakeCaseUTF8Str {
201+
mutable int value;
202+
int get_utf8_string() const { return value; }
203+
void set_utf8_string(int v) { value = v; }
204+
};
205+
194206
#endif // SWIFT_IMPLICIT_COMPUTED_PROPERTIES_H

test/Interop/Cxx/ergonomics/implicit-computed-properties-module-interface.swift

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@
111111
// CHECK: struct IntGetterSetterSnakeCase {
112112
// CHECK-NEXT: init()
113113
// CHECK-NEXT: init(val: Int32)
114+
// CHECK-NEXT: var x: Int32
114115
// CHECK-NEXT: func get_x() -> Int32
115116
// CHECK-NEXT: mutating func set_x(_ v: Int32)
116117
// CHECK-NEXT: var val: Int32
@@ -265,3 +266,21 @@
265266
// CHECK-NEXT: func getValue() -> Int32
266267
// CHECK-NEXT: mutating func setValue(_ i: Int32)
267268
// CHECK-NEXT: }
269+
270+
// CHECK: struct SnakeCaseGetterSetter {
271+
// CHECK-NEXT: init()
272+
// CHECK-NEXT: init(value: Int32)
273+
// CHECK-NEXT: var foo: Int32
274+
// CHECK-NEXT: func get_foo() -> Int32
275+
// CHECK-NEXT: mutating func set_foo(_ v: Int32)
276+
// CHECK-NEXT: var value: Int32
277+
// CHECK-NEXT: }
278+
279+
// CHECK: struct SnakeCaseUTF8Str {
280+
// CHECK-NEXT: init()
281+
// CHECK-NEXT: init(value: Int32)
282+
// CHECK-NEXT: utf8String: Int32
283+
// CHECK-NEXT: func get_utf8_string() -> Int32
284+
// CHECK-NEXT: mutating func set_utf8_string(_ v: Int32)
285+
// CHECK-NEXT: var value: Int32
286+
// CHECK-NEXT: }

test/Interop/Cxx/ergonomics/implicit-computed-properties.swift

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,4 +79,18 @@ ImplicitComputedPropertiesTestSuite.test("non trivial") {
7979
expectEqual(Object.x.value, 20)
8080
}
8181

82+
ImplicitComputedPropertiesTestSuite.test("SnakeCaseGetterSetter") {
83+
var object = SnakeCaseGetterSetter()
84+
expectEqual(object.foo, 42)
85+
object.foo = 32
86+
expectEqual(object.foo, 32)
87+
}
88+
89+
ImplicitComputedPropertiesTestSuite.test("SnakeCaseUTF8Str") {
90+
var object = SnakeCaseUTF8Str()
91+
expectEqual(object.utf8string, 42)
92+
object.utf8string = 32
93+
expectEqual(object.utf8string, 32)
94+
}
95+
8296
runAllTests()

test/SILOptimizer/array_element_propagation_ossa_nontrivial.sil

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ bb0(%arg0 : @owned $MyKlass, %arg1 : @owned $MyKlass, %arg2 : @owned $MyKlass):
204204
return %52 : $()
205205
}
206206

207-
sil [ossa] @unkown_use : $@convention(thin) (@owned MyKlass) -> () {
207+
sil [ossa] @unknown_use : $@convention(thin) (@owned MyKlass) -> () {
208208
bb0(%arg0 : @owned $MyKlass):
209209
%0 = function_ref @swift_bufferAllocate : $@convention(thin) () -> @owned _ContiguousArrayStorage<MyKlass>
210210
%1 = integer_literal $Builtin.Word, 1

test/Sema/availability_define.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,9 @@ public func onMyProjectV3() {}
3838
// expected-error @-1 {{expected version number}}
3939
public func brokenVersion() {}
4040

41-
@available(_unkownMacro, *) // expected-error {{expected declaration}}
41+
@available(_unknownMacro, *) // expected-error {{expected declaration}}
4242
// expected-error @-1 {{expected 'available' option such as 'unavailable', 'introduced', 'deprecated', 'obsoleted', 'message', or 'renamed'}}
43-
public func unkownMacro() {}
43+
public func unknownMacro() {}
4444

4545
@available(_iOS9) // expected-error {{must handle potential future platforms with '*'}}
4646
public func noOtherOSes() {}

utils/build_swift/tests/build_swift/test_driver_arguments.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,7 @@ def test(self):
285285
[option.option_string])
286286
# The argument should never show up in the namespace
287287
self.assertFalse(hasattr(namespace, option.dest))
288-
# It should instead be forwareded to unkown_args
288+
# It should instead be forwareded to unknown_args
289289
self.assertEqual(unknown_args, [option.option_string])
290290

291291
return test

0 commit comments

Comments
 (0)