nicklockwood / SwiftFormat

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

0.49.15 is adding extra indents on any line with `async let` #1250

Closed simondelphia closed 2 years ago

simondelphia commented 2 years ago

After upgrading to 0.49.15 all my lines with async let are getting extra indents

nicklockwood commented 2 years ago

@simondelphia d'oh! thanks, I'll get this fixed.

nicklockwood commented 2 years ago

@simondelphia can you provide a code example? I'm having trouble reproducing this.

nicklockwood commented 2 years ago

I've identified the probable source of the bug and added a fix for it, but it would still be useful to have a test case since I wasn't able to reproduce the issue (cc @calda)

simondelphia commented 2 years ago

I just tried the following in a file in my test folder both with and without the swift format / swift version files as in #1224

func myFunc() {
    let x = 1
    enum Baz {
        case foo
    }
    async let foo = bar()
}

The async let line gets indented more than the other lines when using 0.49.15.

nicklockwood commented 2 years ago

@simondelphia perfect, thanks!

It looks like the issue only happens after a closing brace, but the fix I already landed in develop solves it anyway.

simondelphia commented 2 years ago

Heh, the funny thing is that I just threw that enum in my example randomly

nicklockwood commented 2 years ago

OK, well if you find any other cases that aren't after a brace let me know and I'll add them to the test suite.

In the meantime, I'm not sure of any workarounds other than restructuring the code or adding

// swiftformat:disable:next indent

above the first async let ...

simondelphia commented 2 years ago

Seems to be happening regardless of whether it appears after a closing brace for me

It happens here:

func myFunc() {
    let x = 1
    async let foo = bar()
}

But it doesn't happen if I remove the line let x = 1 or if I move it below the async let instead of above.

choulepoka commented 2 years ago

If it helps the investigation.

Before formatting:

import Foundation

public struct LoadingStateService {

    private let api: Api

    public func willIndent(progress: Progress?) async throws -> Bool {
        progress?.totalUnitCount += 1
        async let serverConfig = try api.getConfig()
        return true
    }

    public func willNotIndent(progress: Progress?) async throws -> Bool {
        async let serverConfig = try api.getConfig()
        return true
    }

    public func willIndent2(progress: Progress?) async throws {
        progress?.totalUnitCount += 1
        async let serverConfig = try api.getConfig()
    }
}

After formatting:

import Foundation

public struct LoadingStateService {

    private let api: Api

    public func willIndent(progress: Progress?) async throws -> Bool {
        progress?.totalUnitCount += 1
            async let serverConfig = try api.getConfig()
        return true
    }

    public func willNotIndent(progress: Progress?) async throws -> Bool {
        async let serverConfig = try api.getConfig()
        return true
    }

    public func willIndent2(progress: Progress?) async throws {
        progress?.totalUnitCount += 1
            async let serverConfig = try api.getConfig()
    }

}
nicklockwood commented 2 years ago

Got it. It seems to be only if the async let if preceded by other code that doesn't begin with async. In any case, all these cases are fixed now. I'll push a new release soon.

nicklockwood commented 2 years ago

Fixed in 0.49.16

simondelphia commented 2 years ago

How long does it usually take for the releases to show up on homebrew?

nicklockwood commented 2 years ago

@simondelphia should be there now

simondelphia commented 2 years ago

All green now, thank you!