-
Notifications
You must be signed in to change notification settings - Fork 10.5k
Add a new driver tool/mode to print the synthesized Swift interface for a module. #76872
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add a new driver tool/mode to print the synthesized Swift interface for a module. #76872
Conversation
@@ -60,6 +60,9 @@ def SupplementaryOutput : OptionFlag; | |||
// The option should be accepted by swift-symbolgraph-extract. | |||
def SwiftSymbolGraphExtractOption : OptionFlag; | |||
|
|||
// The option should be accepted by swift-synthesize-interface. | |||
def SwiftSynthesizeInterfaceOption : OptionFlag; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be ideal if we could unify InterfaceSubContextDelegateImpl::inheritOptionsForBuildingInterface
with something like this.
Because right now if these two get out-of-sync, I imagine this tool may produce outputs that would differ from what the compiler would actually do during compilation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I might be missing the connection here, since the primary goal for this mode is to print the synthesized Swift decls for a C/Obj-C/C++ module. What's the failure case you're thinking of? Someone using this with a .swiftinterface
file on the search path and having it output something different than the interface that would result from compiling it, someone seeing a mismatch between the textual interface and the synthesized interface of an already compiled .swiftmodule
, or something else?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think my mind went in the direction of using a tool like this for Swift code.
It is much less of a concern for C/Obj-C/C++ modules, you're correct.
Someone using this with a .swiftinterface file on the search path and having it output something different than the interface that would result from compiling it, someone seeing a mismatch between the textual interface and the synthesized interface of an already compiled .swiftmodule, or something else?
These are the kinds of failure scenarios I was thinking of, yes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think my mind went in the direction of using a tool like this for Swift code.
It is much less of a concern for C/Obj-C/C++ modules, you're correct.
Since this tool has a similar interface to swift-symbolgraph-extract
, it doesn't take any Swift source files as inputs; it just takes the command line arguments needed to set up the search paths of the compiler instance, and then the module specified by -module-name
will be loaded through the standard mechanisms.
However, using it to dump the interface of an already compiled .swiftmodule
would still be useful. I tested a couple of the cases you were concerned about, and they fail with the expected diagnostics. For example, if I compile a .swiftinterface
and .swiftmodule
for iOS and then try to run swift-synthesize-interface
with -target arm64-apple-macosx14.0
using either the binary module or the textual interface on the search path, I get the following error:
<unknown>:0: error: module 'Module' was created for incompatible target arm64-apple-ios15.0-simulator
Does that address your concerns?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@artemcm Friendly ping—are there any other cases you think I should consider?
@swift-ci please smoke test |
This is the companion of swiftlang/swift#76872. I've reused the `SwiftIndentOption` constant, which was removed by swiftlang/swift#76577 (but Options.swift was never updated here to remove it).
f76bfdc
to
944b5f6
Compare
swiftlang/swift-driver#1709 |
944b5f6
to
4732b92
Compare
swiftlang/swift-driver#1709 |
…or a module. This mode is similar to `swift-symbolgraph-extract`; it takes a subset of compiler flags to configure the invocation for module loading, as well as a module name whose contents should be extracted. It does not take any other input files. The output is a single text file specified by `-o` (or `stdout` if not specified). While the most common use case for this would be viewing the synthesized Swift interface for a Clang module, since the implementation simply calls `swift::ide::printModuleInterface` under the hood, it's usable for any module that Swift can import. Thus, it could also be used to view a synthesized textual representation of, say, a compiled `.swiftmodule`. One could imagine that in the future, we might add more flags to `swift-synthesize-interface` to modify various `PrintOptions` used when generating the output, if we think those would be useful.
4732b92
to
2cfcdd8
Compare
swiftlang/swift-driver#1709 |
This is the companion of swiftlang/swift#76872. I've reused the `SwiftIndentOption` constant, which was removed by swiftlang/swift#76577 (but Options.swift was never updated here to remove it).
This mode is similar to
swift-symbolgraph-extract
; it takes a subset of compiler flags to configure the invocation for module loading, as well as a module name whose contents should be extracted. It does not take any other input files. The output is a single text file specified by-o
(orstdout
if not specified).While the most common use case for this would be viewing the synthesized Swift interface for a Clang module, since the implementation simply calls
swift::ide::printModuleInterface
under the hood, it's usable for any module that Swift can import. Thus, it could also be used to view a synthesized textual representation of, say, a compiled.swiftmodule
.One could imagine that in the future, we might add more flags to
swift-synthesize-interface
to modify variousPrintOptions
used when generating the output, if we think those would be useful.Q: Why not use SourceKit?
SourceKit is great for interactive/IDE experiences, but getting the invocation correct can still be tricky due to subtle differences between SourceKit and the compiler (what the current working directory is, differences between raw vs. Mach-O format .pcm files, convenience, etc.).
So, I'm proposing that we just add a regular compiler invocation that can do this as well. When using a build system like Bazel that builds with explicit modules for C dependencies, it would be trivial to create extra actions that invoke the compiler in this mode and make those synthesized interfaces available to the user to browse. It would also be extremely convenient when debugging what an imported interface looks like if we're working in an environment where Xcode/SourceKit are not convenient to access.