Open soffes opened 9 years ago
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.
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/swift-evolution@swift.org/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...
...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 realswift
. 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:
.dia
), and include that path in the parseable outputI'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!
I haven't found docs yet for the .dia
file format, but here's the code in Clang responsible for reading .dia
files. Should be able to reverse engineer from this worst case:
https://clang.llvm.org/doxygen/SerializedDiagnosticReader_8cpp_source.html
And here's the code responsible for writing .dia
files, which might be more helpful:
https://clang.llvm.org/doxygen/SerializedDiagnosticPrinter_8cpp_source.html
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.