nicklockwood / SwiftFormat

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

SwiftFormat 0.54.0: redundantSelf rule adds invalid "self." prefix #1729

Open yanniks opened 2 weeks ago

yanniks commented 2 weeks ago

After updating to SwiftFormat 0.54.0, we're facing an issue where an invalid self. prefix is added a variable reference. In our example, we're retrieving a view model from the environment and are using @Bindable inside the view to get a bindable reference, like in the following example:

struct MyView: View {
    @Environment(ViewModel.self) var viewModel

    var body: some View {
        @Bindable var viewModel = self.viewModel
        MySubview(
            navigationPath: $viewModel.navigationPath
        )
    }
}

What happens with SwiftFormat 0.54.0, the redundantSelf rule now inserts a self. before the $viewModel.navigationPath which results in the following code:

struct MyView: View {
    @Environment(ViewModel.self) var viewModel

    var body: some View {
        @Bindable var viewModel = self.viewModel
        MySubview(
            navigationPath: self.$viewModel.navigationPath
        )
    }
}

Unfortunately, as self.viewModel is not a Binding, the compilation fails. The issue does not occur with SwiftFormat 0.53.10.

nicklockwood commented 2 weeks ago

@yanniks I'm not able to reproduce the bug with the code sample you've provided. Can you double check?

yanniks commented 2 weeks ago

Hi @nicklockwood , thanks for looking into this!

I have investigated this once more and found out that the issue only occurs if the @Bindable variable definition is not at the same nesting level as the variable use. So while the code example I provided in the original post does not seem to trigger the issue, the following does:

struct MyView: View {
    @Environment(ViewModel.self) var viewModel

    var body: some View {
        @Bindable var viewModel = self.viewModel
        ZStack {
            MySubview(
                navigationPath: $viewModel.navigationPath
            )
        }
    }
}

I have created a GitHub repo that includes an example project which reproduces the issue, including the .swiftformat file which we use.