-
Notifications
You must be signed in to change notification settings - Fork 3.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
update: forward declarations in c and objc #4477
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -914,7 +914,7 @@ Here's the planned deprecation cycle: | |||||
**What's changed?** | ||||||
|
||||||
The JetBrains team has revamped the approach to forward declarations in Kotlin to make their behavior more predictable | ||||||
and prepare this functionality for the upcoming Kotlin 2.0 release. From now on: | ||||||
and prepare this functionality for the Kotlin 2.0.0 release. From now on: | ||||||
|
||||||
* You can only import forward declarations using the `cnames` or ` objcnames` packages. | ||||||
* You need to explicitly make a cast to and from the corresponding C and Objective-C forward declaration. | ||||||
|
@@ -926,48 +926,49 @@ and prepare this functionality for the upcoming Kotlin 2.0 release. From now on: | |||||
Now, you can only use a special forward declaration package for that: `import cnames.structs.cstructName`. | ||||||
The same is true for `objcnames`. | ||||||
|
||||||
* Consider two objcinterop libraries, one that uses `objcnames.protocols.ForwardDeclaredProtocolProtocol` and the other that has an actual definition: | ||||||
|
||||||
```ObjC | ||||||
// First objcinterop library | ||||||
#import <Foundation/Foundation.h> | ||||||
|
||||||
@protocol ForwardDeclaredProtocol; | ||||||
|
||||||
NSString* consumeProtocol(id<ForwardDeclaredProtocol> s) { | ||||||
return [NSString stringWithUTF8String:"Protocol"]; | ||||||
} | ||||||
``` | ||||||
|
||||||
```ObjC | ||||||
// Second objcinterop library | ||||||
// Header: | ||||||
#import <Foundation/Foundation.h> | ||||||
@protocol ForwardDeclaredProtocol | ||||||
@end | ||||||
// Implementation: | ||||||
@implementation ForwardDeclaredProtocolImpl : NSObject | ||||||
@end; | ||||||
|
||||||
id<ForwardDeclaredProtocol> produceProtocol() { | ||||||
return [ForwardDeclaredProtocolImpl new]; | ||||||
} | ||||||
``` | ||||||
|
||||||
Previously, it was possible to transfer objects between them seamlessly. Now, an explicit `as` cast is required | ||||||
for the forward declaration: | ||||||
|
||||||
```kotlin | ||||||
// Kotlin code: | ||||||
fun test() { | ||||||
consumeProtocol(produceProtocol() as objcnames.protocols.ForwardDeclaredProtocolProtocol) | ||||||
} | ||||||
``` | ||||||
|
||||||
> The casting to `objcnames.protocols.ForwardDeclaredProtocolProtocol` is only allowed from the corresponding real class. | ||||||
> Otherwise, you'll get an error. | ||||||
> | ||||||
{style="note"} | ||||||
* Consider two objcinterop libraries, one that uses `objcnames.protocols.ForwardDeclaredProtocolProtocol` and the other | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
that has an actual definition: | ||||||
|
||||||
```ObjC | ||||||
// First objcinterop library | ||||||
#import <Foundation/Foundation.h> | ||||||
|
||||||
@protocol ForwardDeclaredProtocol; | ||||||
|
||||||
NSString* consumeProtocol(id<ForwardDeclaredProtocol> s) { | ||||||
return [NSString stringWithUTF8String:"Protocol"]; | ||||||
} | ||||||
``` | ||||||
|
||||||
```ObjC | ||||||
// Second objcinterop library | ||||||
// Header: | ||||||
#import <Foundation/Foundation.h> | ||||||
@protocol ForwardDeclaredProtocol | ||||||
@end | ||||||
// Implementation: | ||||||
@implementation ForwardDeclaredProtocolImpl : NSObject | ||||||
@end; | ||||||
|
||||||
id<ForwardDeclaredProtocol> produceProtocol() { | ||||||
return [ForwardDeclaredProtocolImpl new]; | ||||||
} | ||||||
``` | ||||||
|
||||||
Previously, it was possible to transfer objects between them seamlessly. Now, an explicit `as` cast is required | ||||||
for the forward declaration: | ||||||
|
||||||
```kotlin | ||||||
// Kotlin code: | ||||||
fun test() { | ||||||
consumeProtocol(produceProtocol() as objcnames.protocols.ForwardDeclaredProtocolProtocol) | ||||||
} | ||||||
``` | ||||||
|
||||||
> The casting to `objcnames.protocols.ForwardDeclaredProtocolProtocol` is only allowed from the corresponding real class. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe it is better to get rid of the passive voice here: You can only cast to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If you'd like to keep the original sentence, the first "The" article is not needed. |
||||||
> Otherwise, you'll get an error. | ||||||
> | ||||||
{style="note"} | ||||||
|
||||||
**When do the changes take effect?** | ||||||
|
||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -228,7 +228,11 @@ A Swift/Objective-C initializer is imported to Kotlin as constructors or as fact | |
The latter happens with initializers declared in the Objective-C category or as a Swift extension, | ||
because Kotlin has no concept of extension constructors. | ||
|
||
Kotlin constructors are imported as initializers to Swift/Objective-C. | ||
> Remember to expose Swift methods with `@objc` before importing Swift initializers to Kotlin. | ||
SvyatoslavScherbina marked this conversation as resolved.
Show resolved
Hide resolved
|
||
> | ||
{type="tip"} | ||
|
||
Kotlin constructors are imported as initializers to Swift/Objective-C. | ||
|
||
### Setters | ||
|
||
|
@@ -569,6 +573,56 @@ binaries.framework { | |
} | ||
``` | ||
|
||
### Forward declarations | ||
|
||
To import forward declarations, use the `objcnames` package. For example, to import a `objcstructName` forward declaration | ||
SvyatoslavScherbina marked this conversation as resolved.
Show resolved
Hide resolved
|
||
declared in an Objective-C library with a `library.package`, use a special forward declaration package: | ||
`import objcnames.structs.objcstructName`. | ||
|
||
To transfer objects between libraries, you need to make an explicit `as` cast to and from the corresponding Objective-C | ||
forward declaration. Consider two objcinterop libraries, one that uses `objcnames.protocols.ForwardDeclaredProtocolProtocol` | ||
and the other that has an actual definition: | ||
|
||
```ObjC | ||
// First objcinterop library | ||
#import <Foundation/Foundation.h> | ||
|
||
@protocol ForwardDeclaredProtocol; | ||
|
||
NSString* consumeProtocol(id<ForwardDeclaredProtocol> s) { | ||
return [NSString stringWithUTF8String:"Protocol"]; | ||
} | ||
``` | ||
|
||
```ObjC | ||
// Second objcinterop library | ||
// Header: | ||
#import <Foundation/Foundation.h> | ||
@protocol ForwardDeclaredProtocol | ||
@end | ||
// Implementation: | ||
@implementation ForwardDeclaredProtocolImpl : NSObject | ||
SvyatoslavScherbina marked this conversation as resolved.
Show resolved
Hide resolved
|
||
@end; | ||
SvyatoslavScherbina marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
id<ForwardDeclaredProtocol> produceProtocol() { | ||
return [ForwardDeclaredProtocolImpl new]; | ||
} | ||
``` | ||
|
||
To transfer objects between them, make the `as` cast in you Kotlin code: | ||
|
||
```kotlin | ||
// Kotlin code: | ||
fun test() { | ||
consumeStruct(produceStruct() as cnames.structs.ForwardDeclaredStruct) | ||
SvyatoslavScherbina marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
``` | ||
|
||
> The casting to `objcnames.protocols.ForwardDeclaredProtocolProtocol` is only allowed from the corresponding real class. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. See the suggestion above. |
||
> Otherwise, you'll get an error. | ||
> | ||
{type="note"} | ||
|
||
## Casting between mapped types | ||
|
||
When writing Kotlin code, an object may need to be converted from a Kotlin type to the equivalent Swift/Objective-C type | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need this line about Kotlin 2.0.0? In my opinion, the following line is more than enough:
"The JetBrains team has revamped the approach to forward declarations in Kotlin to make their behavior more predictable:"