nicklockwood / SwiftFormat

A command-line tool and Xcode Extension for formatting Swift code
MIT License
7.63k stars 623 forks source link

trying to access ObservedObject of parent class requires explicit self. SwiftFormat removes it #1611

Closed flexlixrup closed 5 months ago

flexlixrup commented 5 months ago

I have a NSViewRepresentable with a Coordinator inside this class


import SwiftUI

@MainActor struct FooBar: NSViewRepresentable {
    @ObservedObject var csvState: CSVState
    func makeNSView(context _: Context) -> NSTableView {
        return NSTableView()
    }

    func updateNSView(_: NSTableView, context _: Context) {

    }

    func makeCoordinator() -> Coordinator {
        Coordinator(self)
    }

    typealias NSViewType = NSTableView
    @MainActor class Coordinator: NSObject, NSTableViewDelegate {
        var parent: FooBar
        var tableView: NSTableView?

        init(_ parent: FooBar) {
            self.parent = parent
        }

        func numberOfRows(in _: NSTableView) -> Int {
            10
        }

        func tableView(_: NSTableView, viewFor _: NSTableColumn?, row _: Int) -> NSView? {
            var hostingView = NSHostingView(rootView: BarFoo(csvState: self.parent.csvState)) // Swiftformat removes self here although its explicitly required
            hostingView.identifier = NSUserInterfaceItemIdentifier("foo")
            return NSTextView()
        }
    }
}

struct BarFoo: View {
    @StateObject var csvState: CSVState
    var body: some View {
        Text("hellow rold")
    }
}

In this example Swiftformat tries to remove the self but Swift gives me the following compiler error Reference to property 'parent' in closure requires explicit use of 'self' to make capture semantics explicit

flexlixrup commented 5 months ago

Just discovered that the SwiftUI view should have @ObservedObject var csvState: CSVState instead of @StateObject var csvState: CSVState and then it is safe to remove the self but it's a small bug nevertheless.

nicklockwood commented 5 months ago

@flexlixrup this is a known issue where SwiftFormat can't tell from call-site context that this is a closure. You can workaround it by adding --selfrequired BarFoo to the .swiftformat config.

flexlixrup commented 5 months ago

Ok perfect thanks for the answer. Then this issue can be closed I guess.