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: docs/CToSwiftNameTranslation.md
+240-5Lines changed: 240 additions & 5 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -212,11 +212,249 @@ Additionally, typedefs for `void *` or `const void *` that are themselves annota
212
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
213
214
214
215
+
## Objective-C Methods
216
+
217
+
Objective-C methods are classified into one of five categories:
218
+
219
+
1. Instance methods that are part of the `init` method family whose selector's first word is "init" are considered "normal" initializers.
220
+
221
+
2. Class methods that return the type of the containing class or `instancetype` are considered "factory initializers" if a "leading type match" succeeds against the selector, using the containing type (see [CToSwiftNameTranslation-OmitNeedlessWords.md][]).
222
+
223
+
_As an exception, no-argument factory methods cannot have any additional text *after* the matching portion._
224
+
225
+
3. Accessor methods are associated with a property declaration (`@property`).
226
+
227
+
4. Subscript methods have one of Objective-C's special subscript selectors (`objectAtIndexedSubscript:`, `objectForKeyedSubscript:`, `setObject:atIndexedSubscript:`, or `setObject:forKeyedSubscript:`).
228
+
229
+
5. Other methods are imported as plain methods.
230
+
231
+
If a method overrides a superclass or matches a method in an adopted protocol, the Swift name of the "overridden" method will be used for consistency. If there's more than one such name, one is chosen arbitrarily.
232
+
233
+
234
+
### Normal Initializers
235
+
236
+
The base name of an initializer is always the special name "init". Any leading "init" is dropped from the original selector. If the next word in the first selector piece is "With":
237
+
238
+
1. Drop "With".
239
+
2. If the remaining text is longer than one letter, the first letter is an ASCII uppercase character, and the second letter is *not* an ASCII uppercase character, downcase the first letter.
240
+
3. If the result is a Swift keyword, undo the previous downcasing and insert "with" in front instead.
241
+
4. Set this as the first argument name.
242
+
243
+
Whether or not the initializer will throw is determined according to the "error handling" logic described below. If the initializer is considered throwing, an NSError out-parameter may be removed from the argument list.
244
+
245
+
At this point, the method name goes through the "omit needless words" process described in [CToSwiftNameTranslation-OmitNeedlessWords.md][]. This process attempts to omit superfluous type names and other words that make a name fit the Cocoa Naming Guidelines for Objective-C but not the Swift API Design Guidelines. For initializers, this is based on
246
+
247
+
- the argument types, if any, and whether they'll have default values
248
+
- the first argument name that was just computed and the remaining selector pieces, if any
249
+
250
+
If the resulting name has a first argument name but there are no arguments in the original method, a dummy parameter with type `Void` is added.
251
+
252
+
A normal initializer in a class is considered designated (non-convenience) if it is marked with the `objc_designated_initializer` attribute, *or* if the class has *no* initializers marked with the `objc_designated_initializer` attribute. Otherwise, it is considered convenience.
If an initializer in a class matches a requirement in a protocol adopted by the class, it is imported as `required`.
273
+
274
+
275
+
### Factory initializers
276
+
277
+
The base name of a factory initializer is always the special name "init". The "leading type match" portion of the first selector piece is dropped. If the next word in the first selector piece is "With":
278
+
279
+
1. Drop "With".
280
+
2. If the remaining text is longer than one letter, the first letter is an ASCII uppercase character, and the second letter is *not* an ASCII uppercase character, downcase the first letter.
281
+
3. If the result is a Swift keyword, undo the previous downcasing and insert "with" in front instead.
282
+
4. Set this as the first argument name.
283
+
284
+
Whether or not the initializer will throw is determined according to the "error handling" logic described below. If the initializer is considered throwing, an NSError out-parameter may be removed from the argument list.
285
+
286
+
At this point, the method name goes through the "omit needless words" process described in [CToSwiftNameTranslation-OmitNeedlessWords.md][]. This process attempts to omit superfluous type names and other words that make a name fit the Cocoa Naming Guidelines for Objective-C but not the Swift API Design Guidelines. For factory initializers, this is based on
287
+
288
+
- the argument types, if any, and whether they'll have default values
289
+
- the first argument name that was just computed and the remaining selector pieces, if any
290
+
291
+
Factory initializers are considered convenience initializers if they have a return type of `instancetype`, and a special "non-inherited factory initializer" otherwise.
If a factory initializer turns out to have the same imported name as an available designated initializer, or a non-inherited factory initializer has the same imported name as an available convenience initializer, the factory initializer is marked unavailable to resolve ambiguities. If a convenience factory initializer has the same imported name as an available convenience initializer, the initializer with more restrictive availability is marked unavailable. In the case of a tie, the convenience factory initializer is the one marked unavailable.
308
+
309
+
310
+
### Property accessors
311
+
312
+
A method that has an associated property declaration is imported with a type that matches the property's type and made into a property accessor. See the section on Objective-C properties below.
313
+
314
+
315
+
### Subscript accessors
316
+
317
+
Methods named `objectAtIndexedSubscript:`, `objectForKeyedSubscript:`, `setObject:atIndexedSubscript:`, or `setObject:forKeyedSubscript:` are considered subscript accessors. If a getter method exists on a type, it will be imported as a subscript; a setter method must be paired with a getter method in the same class/protocol, or in a superclass.
318
+
319
+
If a subscript getter and setter disagree about the optionality of the element type, the subscript's element type will be imported as implicitly-unwrapped optional. If the getter and setter element types differ in any other way, the subscript will not be imported. If the getter and setter *index* types differ in any way, the subscript will be imported as read-only.
320
+
321
+
_These two fallbacks should have been the same, but aren't._
322
+
323
+
As a special case, NSDictionary's subscript is imported with a key type of `NSCopying` rather than `Any` so that it has an index type compatible with NSMutableDictionary's subscript setter.
324
+
325
+
326
+
### Normal methods
327
+
328
+
All other Objective-C methods are imported as...methods. Whether or not the method will throw is determined according to the "error handling" logic described below. If the method is considered throwing, an NSError out-parameter may be removed from the argument list.
329
+
330
+
If the first selector piece of the method is empty, the method is not imported into Swift.
331
+
332
+
After any error handling transformations, the method name goes through the "omit needless words" process described in [CToSwiftNameTranslation-OmitNeedlessWords.md][]. This process attempts to omit superfluous type names and other words that make a name fit the Cocoa Naming Guidelines for Objective-C but not the Swift API Design Guidelines. For methods, this is based on
333
+
334
+
- the method base name
335
+
- the method return type
336
+
- the argument types, if any, and whether they'll have default values
337
+
- the first argument name that was just computed and the remaining selector pieces, if any
338
+
- the *local* parameter name for the first parameter
339
+
- the containing class or protocol
340
+
- the set of properties and property-like methods present on the containing class and categories in the same module as the class, including those inherited from superclasses and their categories. (A property-like method is a no-argument method with a non-`void`, non-`instancetype` return type.)
func convert(_ point: CGPoint, to view: UIView?) -> CGPoint
368
+
369
+
var constraints: [NSLayoutConstraint] { get }
370
+
func addConstraint(_ constraint: NSLayoutConstraint) // rather than add(_:)
371
+
}
372
+
```
373
+
374
+
375
+
### Error handling
376
+
377
+
Certain methods with NSError out-parameters are imported as throwing methods in Swift. The conditions for this are as follows:
378
+
379
+
- The method has a parameter with the type `NSError * __autoreleasing *` or `NSError * __unsafe_unretained *`, called the _NSError out-parameter._ Note that `__autoreleasing` is the default for indirect pointers under Objective-C ARC.
380
+
381
+
- The NSError out-parameter is the last parameter in the method other than parameters with block type.
382
+
383
+
- The method provides a way to indicate failure:
384
+
385
+
- an explicit `swift_error` attribute with a value other than `none`, or
386
+
- a return type of `BOOL` or `Boolean`, or
387
+
- a return type that will be imported as Optional
388
+
389
+
Note that the built-in `bool` (`_Bool`) type is *not* considered a boolean type for the purposes of inferring "throws".
390
+
391
+
- The method does not have a `swift_error` attribute with a value of `none`.
392
+
393
+
If the method in question is not going to be imported as an initializer, and the NSError out-parameter is the first parameter, and the first selector piece ends with "AndReturnError" or "WithError", the matching suffix is dropped from the base name unless the resulting base name would be a Swift keyword. If the NSError out-parameter is *not* the first parameter, the corresponding selector piece is dropped entirely. The modified selector is then compared against other methods in the class. If there are no other methods in the class matching the new selector, the name change is accepted; otherwise, the original selector is used.
If the original selector was used and no "AndReturnError" or "WithError" suffix-stripping was attempted, the imported method will have a dummy parameter with type `Void` in place of the NSError out-parameter. In all other cases (a modified selector or a selector with a suffix that could have been stripped), the NSError out-parameter is removed from the method.
The return type will be transformed according to the kind of failure indication:
426
+
427
+
-`swift_error(nonnull_error)`: no transformation
428
+
-`swift_error(null_result)` (default for Optional return types): return type becomes non-optional
429
+
-`swift_error(zero_result)` (default for `BOOL` and `Boolean`): `BOOL` and `Boolean` become `Void`; other return types are unchanged
430
+
-`swift_error(nonzero_result)`: return type becomes `Void`
431
+
432
+
433
+
### Default argument values
434
+
435
+
Certain method parameters are automatically considered to have default argument values when imported into Swift. This inference uses the following algorithm:
436
+
437
+
1. If the first word of the method base name is "set", the first parameter of that method never has a default value.
438
+
439
+
2. A final argument that is a nullable function or block pointer defaults to `nil`.
440
+
441
+
3. A nullable argument of type `NSZone *` defaults to `nil`.
442
+
443
+
4. An argument whose type is an option set enum (see above) where the C name of the enum contains the word "options" defaults to `[]`.
444
+
445
+
_This mistakenly does not check the names of typedefs that wrap anonymous enums, which are supposed to be treated as the name of the enum._
446
+
447
+
5. An argument whose Objective-C type is an NSDictionary defaults to `nil` if the NSDictionary is nullable and `[:]` if the NSDictionary is non-nullable, under the following conditions:
448
+
449
+
- the argument label contains the word "options" or "attributes", or the two words "user info" one after another
450
+
- the argument label is empty and the method base name ends with the word "options" or "attributes", or the two words "user info" one after another
451
+
452
+
215
453
## Objective-C Properties
216
454
217
455
Property names are transformed according to the "omit needless words" process described in [CToSwiftNameTranslation-OmitNeedlessWords.md][]. This process attempts to omit superfluous type names and other words that make a name fit the Cocoa Naming Guidelines for Objective-C but not the Swift API Design Guidelines. The transformation is based on the property's type and the type of the enclosing context.
218
456
219
-
If the getter of a property overrides a superclass or adopted protocol method that is also a property accessor, the Swift name of the overridden accessor's property will be used for consistency. If there's more than one such name, one is chosen arbitrarily.
457
+
If the getter of a property overrides a superclass method or matches a method in an adopted protocol that is also a property accessor, the Swift name of the "overridden" accessor's property will be used for consistency. If there's more than one such name, one is chosen arbitrarily.
220
458
221
459
Properties with the type `BOOL` or `Boolean` use the name of the getter as the name of the Swift property by default, rather than the name of the property in Objective-C. This accounts for a difference in Swift and Objective-C naming conventions for boolean properties that use "is".
222
460
@@ -241,7 +479,7 @@ _Objective-C code has historically not been consistent about whether the NSAcces
241
479
242
480
## `swift_private`
243
481
244
-
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.
482
+
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 or matches a protocol requirement; in that case the name needs to match the "overridden" declaration.
245
483
246
484
```objc
247
485
@interfaceExample : NSObject
@@ -537,6 +775,3 @@ init(default: ())
537
775
A custom name on an instance method with one of Objective-C's subscript selectors (`objectAtIndexedSubscript:`, `objectForKeyedSubscript:`, `setObject:atIndexedSubscript:`, or `setObject:forKeyedSubscript:`) prevents that method from being imported as a subscript or used as the accessor for another subscript.
538
776
539
777
_Currently, this only works if *both* methods in a read/write subscript are given custom names; if just one is, a read/write subscript will still be formed. A read-only subscript only has one method to rename._
0 commit comments