Swiftlint: Fix it?

Created on 22 May 2015  Â·  24Comments  Â·  Source: realm/SwiftLint

Not sure if you can provide fix its, but that would be super cool. For some rules (i.e. whitespace only on a line) it would be pretty easy to figure out what to change. Obviously for stuff like as! you shouldn't suggest one.

enhancement wontfix

Most helpful comment

Hello old issue,

I thought of replacing the swift executable with a custom executable that does its own thing and then calls the real swift. It would probably work, but that kind of hack has a nefarious feel to it.

You can do this in a less invasive way by setting SWIFT_EXEC in the build settings. You could create a wrapper script that calls both swiftc and calls swiftlint.

To make this work, swiftlint would need two features:

  1. Generate parseable output, see Swift's docs/DriverParseableOutput.rst
  2. Generate a diagnostics file (.dia), and include that path in the parseable output

I'm not sure where the diagnostic file format is documented.

All 24 comments

Related: #5

Closing dupe. Sorry.

@soffes I actually don't think this is necessarily a dupe as it's a subset. It might make sense to implement this and not #5.

You're right, not a dupe! Do you happen to know if Xcode exposes an API to provide fix-its?

So far, we've been able to avoid making an Xcode plugin and I'd love to continue that in the future :smile:

Not sure. Hopefully there's a way without it :)

Pretty sure the fix-it's come from the errors/warnings themselves (I.e. The text)

@segiddins do you know what the format should be to suggest a fix-it to Xcode?

It would be very useful even if it's just a cli command for now: swiftlint fix

@julien-c I think you're confusing "Xcode Fix-Its" (this issue), with #5 (the ability to automatically correct violations).

More info on Xcode Fix-Its can be found in Apple's documentation: https://developer.apple.com/library/ios/recipes/xcode_help-source_editor/chapters/Fix-it.html

According to people on the dev tools team, there's no public way to add new fix-its

Then the private way it will be!

@segiddins what is the private way to add fix-it?

The new xcode 8 extensions are interesting but probably not applicable here.
Using and Extending the Xcode Source Editor at min20 they start talking about extensions

what is the private way to add fix-it?

Xcode Plugins, and no, Xcode Source Extensions don't expose a way to do that, so this would have to be done in an Alcatraz-style Xcode plugin.

I’ve tried to get this to work in my own project to no avail.

It is easy enough to output the same syntax as swift build (roughly the same as Clang). The problem is that Xcode ignores them in “run script” build phases.

If you add a “run script” build phase with...

swift build

...none of the errors will have fix‐its, even where the build log has defined them.

Note: By “Fix‐It”, I mean the ability to click on the yellow triangle for a suggestion and the ability to do “Fix All in Scope” or ⌃⌄⌘F.

If anyone knows of a way of tricking Xcode into running a shell script within a “compile sources” build phase, I think that would get us most of the way toward a solution.

If anyone knows of a way of tricking Xcode into running a shell script within a “compile sources” build phase, I think that would get us most of the way toward a solution.

I think you could set up an external build system target and have that as a target dependency to your current target.

image

image

image

I think you could set up an external build system target...

@jpsim, it was a great idea. Unfortunately when I tried it (with swift build) there were still no fix‐its, just plain errors. Xcode apparently does not parse the output of external build targets for fix‐its either.

Sounds like the swift compiler generates the fixits?
https://www.mail-archive.com/[email protected]/msg23204.html

"FYI, this fixit is entirely generated by the swift compiler, not Xcode. The
swift compiler is fully open source and generally welcomes well formed patches.

-Chris"

FYI, this fixit is entirely generated by the swift compiler, not Xcode.

@masters3d, yes, the Swift compiler defines the locations and replacements of the fix‐its. The output of swift build (visible in the Xcode build log) contains entries like this:

/Users/JohnDoe/Project/Sources/Module/File.swift:2:9: warning: initialization of immutable value 'x' was never used; consider replacing with assignment to '_' or removing it
    let x = 0
    ~~~~^
    _

The ^ marks the location (as well as the line and column :2:9), the ~s mark the replacement range, and the _ is the suggested replacement.

The problem is that Xcode is responsible for actually implementing the fix‐it with clickable yellow triangles and ⌃⌄⌘F.

When Xcode runs swift during a “compile sources” phase, it parses the output looking for fix‐its and implements them.
However, when the same swift command is run...

  • in a “run script” build phase (the current SwiftLint way),
  • as an external build command (JP Simard’s idea above), or
  • presumably anywhere else in the build process...

...Xcode parses the output looking for errors but does not try looking for fix‐its, effectively ignoring all but the first line of the example above.

That is why mimicking the fix‐its produced by swift, would probably work within a “compile sources” phase, but would be ignored by Xcode anywhere else.


I thought of replacing the swift executable with a custom executable that does its own thing and then calls the real swift. It would probably work, but that kind of hack has a nefarious feel to it.

I thought of replacing the swift executable with a custom executable that does its own thing and then calls the real swift. It would probably work, but that kind of hack has a nefarious feel to it.

Was going to say this too. Not too nefarious (actually very similar to how swiftenv works), and certainly not as messy as Xcode plugins of yore.

It _might_ actually be possible to render fix-its from external build phases: https://clang.llvm.org/docs/UsersManual.html#cmdoption-fdiagnostics-parseable-fixits

I'm not sure because I haven't been able to get anything in that format or variations thereof to display in Xcode.

It might actually be possible to render fix-its from external build phases [...]

Probably the easiest test is to have something that generates fix‐its when Xcode builds it in a normal build phase (using clang). Then add an external build phase that tells clang to do the same thing. That will tell us whether Xcode is even listening for them.

The same test failed for me when I was trying it with swift instead of clang.

@jpsim, thanks for thinking more about it. Keep us posted if you make any progress.

Hello old issue,

I thought of replacing the swift executable with a custom executable that does its own thing and then calls the real swift. It would probably work, but that kind of hack has a nefarious feel to it.

You can do this in a less invasive way by setting SWIFT_EXEC in the build settings. You could create a wrapper script that calls both swiftc and calls swiftlint.

To make this work, swiftlint would need two features:

  1. Generate parseable output, see Swift's docs/DriverParseableOutput.rst
  2. Generate a diagnostics file (.dia), and include that path in the parseable output

I'm not sure where the diagnostic file format is documented.

This issue has been automatically marked as stale because it has not had any recent activity. Please comment to prevent this issue from being closed. Thank you for your contributions!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

marcelofabri picture marcelofabri  Â·  19Comments

gorbat-o picture gorbat-o  Â·  21Comments

geoffreywiseman picture geoffreywiseman  Â·  16Comments

Oliver-Kirkland-Evoke picture Oliver-Kirkland-Evoke  Â·  31Comments

RussVanBert picture RussVanBert  Â·  19Comments