diff --git a/Sources/SwiftExtract/SwiftTypes/SwiftFunctionSignature.swift b/Sources/SwiftExtract/SwiftTypes/SwiftFunctionSignature.swift index 08201f5a7..34a94163b 100644 --- a/Sources/SwiftExtract/SwiftTypes/SwiftFunctionSignature.swift +++ b/Sources/SwiftExtract/SwiftTypes/SwiftFunctionSignature.swift @@ -545,17 +545,19 @@ extension VariableDeclSyntax { return [.get] } - if let accessorBlock = binding.accessorBlock { - return accessorBlock.supportedAccessorKinds() - } - - // Account for private(set) and similar modifiers + // Account for private(set) and similar modifiers. This is checked before the + // accessor block, because a variable can restrict its setter's access level and + // still spell out its accessors explicitly. for modifier in self.modifiers where modifier.detail?.detail.text == "set" { if !minimumAccessLevel.matches(modifier) { return [.get] } } + if let accessorBlock = binding.accessorBlock { + return accessorBlock.supportedAccessorKinds() + } + return [.get, .set] } } diff --git a/Tests/JExtractSwiftTests/VariableImportTests.swift b/Tests/JExtractSwiftTests/VariableImportTests.swift index f2ffde174..8538af4d2 100644 --- a/Tests/JExtractSwiftTests/VariableImportTests.swift +++ b/Tests/JExtractSwiftTests/VariableImportTests.swift @@ -154,4 +154,38 @@ final class VariableImportTests { ] ) } + + let class_privateSetWithAccessorBlockInterfaceFile = + """ + public class MySwiftClass { + public private(set) var counterInt: Int { + get { fatalError() } + set { fatalError() } + } + } + """ + + @Test("Import: public private(set) var counterInt: Int with an explicit accessor block emits only the getter") + func variable_int_privateSet_explicitAccessorBlock() throws { + try assertOutput( + input: class_privateSetWithAccessorBlockInterfaceFile, + .ffm, + .java, + swiftModuleName: "FakeModule", + detectChunkByInitialLines: 1, + expectedChunks: [ + """ + public long getCounterInt() throws SwiftIntegerOverflowException { + $ensureAlive(); + long result$checked = swiftjava_FakeModule_MySwiftClass_counterInt$get.call(this.$memorySegment()); + ... + } + """ + ], + notExpectedChunks: [ + "swiftjava_FakeModule_MySwiftClass_counterInt$set", + "setCounterInt", + ] + ) + } }