swift-macro-testing icon indicating copy to clipboard operation
swift-macro-testing copied to clipboard

Exclusively applicable fix-its aren't testable

Open gohanlon opened this issue 7 months ago • 5 comments

Description

I have a diagnostic with several fix-its, where only one can be applied. Here's the usage, and note that, while diagnostics is correct and (very!) useful, both fixes and expansion are nonsensical:

assertMacro {
  """
  @MemberwiseInit
  struct S {
    @Init(default: "Blob") var name = "Foo"
  }
  """
} diagnostics: {
  """
  @MemberwiseInit
  struct S {
    @Init(default: "Blob") var name = "Foo"
          ┬──────────────
          ╰─ 🛑 Custom 'default' can't be applied to already initialized variable
             ✏️ Remove 'default: "Blob"'
             ✏️ Remove '@Init(default: "Blob")'
             ✏️ Remove '= "Foo"'
  }
  """
} fixes: {
  """
  @MemberwiseInit
  struct S {
    @Init
  }
  """
} expansion: {
  """
  struct S {
    @Init

    internal init() {
    }
  }
  """
}

To show the actual fix-it behavior applied in Xcode, here's a theoretical array syntax format:

…
} fixes: {
  [
    """
    @MemberwiseInit
    struct S {
      @Init var name = "Foo"
    }
    """,
    """
    @MemberwiseInit
    struct S {
      var name = "Foo"
    }
    """,
    """
    @MemberwiseInit
    struct S {
      @Init(default: "Blob") var name: String
    }
    """,
  ]
} expansion: {
…

And, a theoretical dictionary syntax format:

} fixes: {
  [
    #"✏️ Remove 'default: "Blob"'"#:
    """
    @MemberwiseInit
    struct S {
      @Init var name = "Foo"
    }
    """,
    #"✏️ Remove '@Init(default: "Blob")'"#:
    """
    @MemberwiseInit
    struct S {
      var name = "Foo"
    }
    """,
    #"✏️ Remove '= "Foo"'"#:
    """
    @MemberwiseInit
    struct S {
      @Init(default: "Blob") var name: String
    }
    """,
  ]
} expansion: {

What do you think?

P.S.: swift-macro-testing is great—I'm heavily using/abusing it. Thank you!

Checklist

  • [X] If possible, I've reproduced the issue using the main branch of this package.
  • [X] This issue hasn't been addressed in an existing GitHub issue or discussion.

Expected behavior

Each fix-it should be applied to the original source independently, each producing a corresponding fixed-source string.

Actual behavior

It's assumed that all fix-its can always be applied on top of each other, accumulating into a single string.

Steps to reproduce

No response

swift-macro-testing version information

0.2.2

Destination operating system

macOS 14.1.2

Xcode version information

Xcode Version 15.0.1 (15A507)

Swift Compiler version information

swift-driver version: 1.87.1 Apple Swift version 5.9 (swiftlang-5.9.0.128.108 clang-1500.0.40.1)
Target: arm64-apple-macosx14.0

gohanlon avatar Dec 06 '23 06:12 gohanlon