Skip to content

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

Merged
merged 1 commit into from
Oct 18, 2024

Conversation

allevato
Copy link
Member

@allevato allevato commented Oct 4, 2024

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.

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.

@allevato
Copy link
Member Author

allevato commented Oct 7, 2024

cc: @ahoppen @bnbarham

@@ -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;
Copy link
Contributor

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.

Copy link
Member Author

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?

Copy link
Contributor

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.

Copy link
Member Author

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?

Copy link
Member Author

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?

@allevato
Copy link
Member Author

allevato commented Oct 8, 2024

@swift-ci please smoke test

allevato added a commit to allevato/swift-driver that referenced this pull request Oct 9, 2024
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).
@allevato allevato force-pushed the swift-synthesize-interface-tool branch from f76bfdc to 944b5f6 Compare October 9, 2024 14:32
@allevato
Copy link
Member Author

allevato commented Oct 9, 2024

swiftlang/swift-driver#1709
@swift-ci please smoke test

@allevato allevato force-pushed the swift-synthesize-interface-tool branch from 944b5f6 to 4732b92 Compare October 9, 2024 14:34
@allevato
Copy link
Member Author

swiftlang/swift-driver#1709
@swift-ci please test Windows platform

…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.
@allevato allevato force-pushed the swift-synthesize-interface-tool branch from 4732b92 to 2cfcdd8 Compare October 10, 2024 19:30
@allevato
Copy link
Member Author

swiftlang/swift-driver#1709
@swift-ci please smoke test

artemcm pushed a commit to swiftlang/swift-driver that referenced this pull request Oct 18, 2024
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).
@allevato allevato merged commit bd4cfee into swiftlang:main Oct 18, 2024
3 checks passed
@allevato allevato deleted the swift-synthesize-interface-tool branch October 18, 2024 17:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants