[jextract] Improve Cdecl lowering#238
Conversation
| /// Convert the conversion step into an expression with the given | ||
| /// value as the placeholder value in the expression. | ||
| func asExprSyntax(isSelf: Bool, placeholder: String) -> ExprSyntax { | ||
| func asExprSyntax(placeholder: String, bodyItems: inout [CodeBlockItemSyntax]) -> ExprSyntax? { |
There was a problem hiding this comment.
Using bodyItems, ConversionStep can now introduce side effects, for example it can store the inner step into a variable, then return the DeclReferenceExprSyntax to it.
DougGregor
left a comment
There was a problem hiding this comment.
This looks fantastic, thank you!
| /// providing all of the mappings between the parameter and result types | ||
| /// of the original function and its `@_cdecl` counterpart. |
There was a problem hiding this comment.
Total nit, but there's no parameter or result type for a variable, just the type itself.
| if let generics = node.genericParameterClause { | ||
| throw SwiftFunctionTranslationError.generic(generics) | ||
| } |
There was a problem hiding this comment.
Thank you for making it defensive like this
| hasGetter = true | ||
| case .keyword(.set), .keyword(._modify), .keyword(.unsafeMutableAddress): | ||
| hasSetter = true | ||
| default: // Ignore willSet/didSet and unknown accessors. |
There was a problem hiding this comment.
willSet/didSet imply that we have both getter and setter, don't they?
| switch (hasGetter, hasSetter) { | ||
| case (true, true): return [.get, .set] | ||
| case (true, false): return [.get] | ||
| case (false, true): return [.set] |
There was a problem hiding this comment.
Technically, this case is unreachable in well-formed code
There was a problem hiding this comment.
Ohh, I didn't know setter only variables are prohibited in Swift 😅
| expectedCDecl: """ | ||
| @_cdecl("c_takeString") | ||
| public func c_takeString(_ str: UnsafePointer<Int8>) { | ||
| takeString(str: String(cString: str)) |
* Newly introduce `lowerResult()` (splitted from `lowerParameter()` because result lowering can be differnt from parameter lowering. * Remove `ConversionStep.init(cdeclToSwift:)/.init(swiftToCdecl:)`. Instead embed the logic in `lowerParameter()`/`lowerResult()` so that we can implement type lowering and the actual conversion at the same place. * Support 'String', 'Void' and '() -> Void) types * Implement getter / setter lowering * Fix conversion for tuple returns (see: `lowerTupleReturns()` test) * Reference types are now returned indirectly, as the logic are being unifed. Thanks to this we don't need manual `retain()` before returning instances, which wasn't implemented correctly.
01b8081 to
bcd5e0e
Compare
Part of #236 with some test cases.
Cdecl lowering improvements without integrating into the actual workflow.
lowerResult()(splitted fromlowerParameter()because result lowering can be differnt from parameter lowering.ConversionStep.init(cdeclToSwift:)/.init(swiftToCdecl:). Instead embed the logic inlowerParameter()/lowerResult()so that we can implement type lowering and the actual conversion at the same place.lowerTupleReturns()test)retain()before returning instances, which wasn't implemented correctly.