You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: branches/master-rebranch/docs/CToSwiftNameTranslation.md
+59-10Lines changed: 59 additions & 10 deletions
Original file line number
Diff line number
Diff line change
@@ -2,6 +2,19 @@
2
2
3
3
This document gives a high-level description of how C and Objective-C declarations are translated to Swift, with particular focus on how names are adjusted. It is not attempting to be a *complete* description of everything the compiler does except with regards to how *names* are transformed; even there, some special cases that only apply to Apple's SDKs have been omitted.
4
4
5
+
## Word boundaries
6
+
7
+
Several forms of name translation are defined in terms of word boundaries. The word-splitting algorithm used by the Swift compiler is as follows: there is a boundary after
8
+
9
+
1. An underscore ("\_").
10
+
2. A series of two or more uppercase ASCII characters and the suffix "s", "es", or "ies" (e.g. "URLs", "VAXes")...unless the last uppercase letter is "I" and the suffix is "s", in which case it's just as likely to be an acronym followed by "Is" (i.e. "URLIs" is treated as "URL Is").
11
+
2. A series of two or more uppercase ASCII characters followed by an uppercase ASCII character and then a lowercase ASCII character ("XMLReader" becomes "XML Reader").
12
+
3. A series of two or more uppercase ASCII characters followed by a non-ASCII-alphabetic character. ("UTF8" becomes "UTF 8")
13
+
4. A series of two or more uppercase ASCII characters at the end of the string.
14
+
5. An uppercase ASCII character and any number of non-ASCII-uppercase, non-underscore characters ("ContrivedExample" becomes "Contrived Example").
15
+
6. Any number of non-ASCII-uppercase, non-underscore characters ("lowercase\_example" becomes "lowercase \_ example").
16
+
17
+
5
18
## Enums
6
19
7
20
1. Anonymous? Import elements as constants of the underlying type, *except* that Int is used for an inferred underlying type if all the cases fit in an Int32, since integer conversions are explicit in Swift.
@@ -114,15 +127,7 @@ In C, enumerators (enum cases) aren't namespaced under their enum type, so their
114
127
115
128
1. Collect all *available, non-deprecated* enum cases *without custom names.* If there are no such cases, collect all cases without custom names, whether available or not.
116
129
117
-
2. Find the common word-boundary prefix __CP__ of these cases. There is a word boundary after
118
-
119
-
1. An underscore ("\_").
120
-
2. A series of two or more uppercase ASCII characters and the suffix "s", "es", or "ies" (e.g. "URLs", "VAXes")...unless the last uppercase letter is "I" and the suffix is "s", in which case it's just as likely to be an acronym followed by "Is" (i.e. "URLIs" is treated as "URL Is").
121
-
2. A series of two or more uppercase ASCII characters followed by an uppercase ASCII character and then a lowercase ASCII character ("XMLReader" becomes "XML Reader").
122
-
3. A series of two or more uppercase ASCII characters followed by a non-ASCII-alphabetic character. ("UTF8" becomes "UTF 8")
123
-
4. A series of two or more uppercase ASCII characters at the end of the string.
124
-
5. An uppercase ASCII character and any number of non-ASCII-uppercase, non-underscore characters ("ContrivedExample" becomes "Contrived Example").
125
-
6. Any number of non-ASCII-uppercase, non-underscore characters ("lowercase\_example" becomes "lowercase \_ example").
130
+
2. Find the common word-boundary prefix __CP__ of these cases.
126
131
127
132
3. If __CP__ starts with "k" followed by an uppercase letter, or if it's *just* "k" and none of the cases have a non-identifier-start character immediately after the 'k', treat that as meaning "constant" and ignore it for the next step.
128
133
@@ -144,7 +149,7 @@ In C, enumerators (enum cases) aren't namespaced under their enum type, so their
144
149
145
150
9. ASCII-lowercase the first word of the remaining name if it starts with an uppercase ASCII character.
146
151
147
-
_There's a bug here where the special case for "Is" is missing, so "URLIs" will be lowercased to "urlis"._
152
+
_There's a bug in this step where the special case for "Is" is missing, so "URLIs" will be lowercased to "urlis"._
148
153
149
154
## `swift_wrapper` typedefs
150
155
@@ -190,4 +195,48 @@ extension SecretResourceID {
190
195
191
196
On Apple platforms, whenever Foundation is imported, constants with the type "NSNotificationName" additionally have the suffix "Notification" stripped before performing the above rules unless they have a custom name. Global NSString constants whose name ends in "Notification" will also automatically be treated as if they were declared with the type NSNotificationName unless they have a custom name.
192
197
198
+
199
+
## Objective-C Protocols
200
+
201
+
Protocols in Objective-C are normally in a separate namespace from the "ordinary" identifier namespace used by typedefs and classes. Swift does not have separate namespaces, so if the protocol has the same name as another declaration in the same module, the suffix "Protocol" is appended. (Example: NSObjectProtocol in the ObjectiveC module.)
202
+
203
+
204
+
## CF Types
205
+
206
+
"Core Foundation" is a C-based object-oriented system with strong conventions built around pointers to opaque structs. Creating new Core Foundation types is not generally supported, but Swift will recognize those in Apple's SDKs. If a struct has the `objc_bridge`, `objc_mutable_bridge`, or `objc_bridge_related` Clang attributes, it will be treated as a CF type and a typedef of a pointer to that struct will be imported as a class in Swift. The suffix "Ref" will be dropped from the class's name if present unless doing so would conflict with another declaration in the same module as the typedef.
207
+
208
+
If the class name contains the word "Mutable" exactly once per the usual word-boundary rules, a corresponding class name without the word "Mutable" will be used as the superclass if present. Otherwise, the CF type is taken to be a root object.
209
+
210
+
Additionally, typedefs for `void *` or `const void *` that are themselves annotated with `objc_bridge` will be treated as CFTypeRef-like and imported as `Any` rather than `Unsafe[Mutable]RawPointer`.
211
+
212
+
If a typedef's underlying type is itself a "CF pointer" typedef, the "alias" typedef will be imported as a regular typealias, with the suffix "Ref" still dropped from its name (if present) unless doing so would conflict with another declaration in the same module as the typedef.
213
+
214
+
215
+
## `swift_private`
216
+
217
+
The `swift_private` Clang attribute prepends `__` onto the base name of any declaration being imported except initializers. For initializers with no arguments, a dummy `Void` argument with the name `__` is inserted; otherwise, the label for the first argument has `__` prepended. This transformation takes place after any other name manipulation, unless the declaration has a custom name. It will not occur if the declaration is an override; in that case the name needs to match the overridden declaration.
@property(readonly) int value __attribute__((swift_private));
223
+
@end
224
+
225
+
// Usually seen as NS_REFINED_FOR_SWIFT
226
+
```
227
+
228
+
```swift
229
+
class Example: NSObject {
230
+
init(__value: Int32)
231
+
var __value: Int32 { get }
232
+
}
233
+
```
234
+
235
+
The purpose of this annotation is to allow a more idiomatic implementation to be provided in Swift. The effect of `swift_private` is inherited from an enum onto its elements if the enum is not imported as an error code enum, an `@objc` enum, or an option set.
236
+
237
+
_The original intent of the `swift_private` attribute was additionally to limit access to a Swift module with the same name as the owning Clang module, e.g. the Swift half of a mixed-source framework. However, this restriction has not been implemented as of Swift 5.1._
238
+
239
+
_For "historical reasons", the `swift_private` attribute is ignored on factory methods with no arguments imported as initializers. This is essentially matching the behavior of older Swift compilers for source compatibility in case someone has marked such a factory method as `swift_private`._
0 commit comments