Resolves rdar://151911998
This PR addresses an uncommon situation in the symbol graph when
importing Objective-C symbols into Swift. When a class conforms to a
protocol that includes an initializer, that initializer is automatically
generated for that class in the AST. This initializer has the same USR
as the original protocol symbol, but is housed in a different
DeclContext to indicate the membership.
Right now, we catch this situation when the protocol conformance is
declared on the class definition: There's a branch to check for
"implicit" decls with an underlying Clang symbol, and creates a
synthesized USR if that symbols DeclContext points to a type. However,
when the protocol conformance is added in a category extension, the
DeclContext for the generated initializer points to the extension,
causing the symbol to bypass that check and get added to the symbol
graph with a duplicated USR. This PR adds a check to look for
ExtensionDecls as the DeclContext so that the symbol can correctly
receive a synthesized USR.
One of the tests in this PR
(`SymbolGraph/ClangImporter/ObjCInitializer.swift`) tests a similar
situation where this "implicit decl with a Clang node" is created: Some
initializers in Objective-C get imported into Swift twice, with
differently-adapted parameter names. This is covered by the original
code, but i wanted to leave the test in because i broke this case in my
initial investigation! 😅 The other test
(`SymbolGraph/ClangImporter/ProtocolInitializer.swift`) tests the new
behavior that is fixed by this PR.
Resolves rdar://152676102
In Objective-C, it's reasonable to sort extensions of your dependency's
types into headers that match the name of that type. However, this runs
into a bug in SymbolGraphGen when it comes time to generate Swift symbol
graphs for that Objective-C code: At the moment, it only differentiates
between modules based on their base name, regardless of their parent
modules (if any). This causes these extensions to be incorrectly sorted
into the _extending module's_ symbol graph, rather than in an extension
symbol graph where it can be displayed with the _extended module_. When
processed with Swift-DocC, it would cause these symbols to disappear.
This PR updates the `areModulesEqual` function used by the
`SymbolGraphASTWalker` to consider the fully-qualified module name for
comparisons, rather than just the module's base name, causing situations
like the test's `Dependency.DependencyClass` and
`HeaderCollision.DependencyClass` to be properly distinguished from each
other.
* Revert "Revert "[SymbolGraphGen] synthesize child symbols for type aliases of private…" (#79062)"
This reverts commit cac82978bc.
* clean up use of DenseMap in SymbolGraphGen
rdar://143865173
It replaces `DeclAttr::getUnavailable()` and `AvailableAttr::isUnavailable()`
as the designated way to query for the attribute that makes a decl unavailable.
Getting a result from `DeclAttrs::getUnavailable()` already indicates that the
declaration is either fully unavailable or obsoleted. Checking
`AvailableAttr::getVersionAvailability()` is redundant.
This change is two fold. Firstly it enables collection of exported
imports from non source file units. Additionally this recurses through
the exported imports to ensure the transitive set is collected.
Fixes https://github.com/apple/swift/issues/59920
rdar://89687175
This is phase-1 of switching from llvm::Optional to std::optional in the
next rebranch. llvm::Optional was removed from upstream LLVM, so we need
to migrate off rather soon. On Darwin, std::optional, and llvm::Optional
have the same layout, so we don't need to be as concerned about ABI
beyond the name mangling. `llvm::Optional` is only returned from one
function in
```
getStandardTypeSubst(StringRef TypeName,
bool allowConcurrencyManglings);
```
It's the return value, so it should not impact the mangling of the
function, and the layout is the same as `std::optional`, so it should be
mostly okay. This function doesn't appear to have users, and the ABI was
already broken 2 years ago for concurrency and no one seemed to notice
so this should be "okay".
I'm doing the migration incrementally so that folks working on main can
cherry-pick back to the release/5.9 branch. Once 5.9 is done and locked
away, then we can go through and finish the replacement. Since `None`
and `Optional` show up in contexts where they are not `llvm::None` and
`llvm::Optional`, I'm preparing the work now by going through and
removing the namespace unwrapping and making the `llvm` namespace
explicit. This should make it fairly mechanical to go through and
replace llvm::Optional with std::optional, and llvm::None with
std::nullopt. It's also a change that can be brought onto the
release/5.9 with minimal impact. This should be an NFC change.
fix a crash in symbol graph generation caused by an empty SmallVector access while expanding protocol compositions during conformance expansion for extension block symbols
rdar://103322385
`getValue` -> `value`
`getValueOr` -> `value_or`
`hasValue` -> `has_value`
`map` -> `transform`
The old API will be deprecated in the rebranch.
To avoid merge conflicts, use the new API already in the main branch.
rdar://102362022
This includes:
- bumping the SWIFT_SYMBOLGRAPH_FORMAT_MINOR version
- introduction of the "swift.extension" symbol and "extensionTo" relationship
- adding support for ExtensionDecl to the Symbol class
- adding a "typeKind" field to the symbol's extension mixin which indicates what kind
of symbol was extended
- intoduction of the -emit-extension-block-symbols flag, which enables the behavior
outlined below
- adaptions to SymbolGraphASTWalker that ensure a swift.extension symbol is emitted
for each extension to a type that does not exist in the local symbol graph
- adaptions to SymbolGraph and SymbolGraphASTWalker that ensure member and conformance
relationships are correctly associated with the swift.extension symbol instead of
the original type declaration's (extended nominal's) symbol where applicable
- adaptions to SymbolGraphASTWalker that ensure swift.extension symbols are connected
to their respective extended nominal's symbol using an extensionTo relationship
Testing:
- adds SymbolGraph tests that test behavior only relevant in
-emit-extension-block-symbols mode
- adapts some SymbolGraph tests to additionally test similar behavior for
extensions to external types in -emit-extension-block-symbols mode
- adapts some SymbolGraph tests to (additionally or exclusively) test the
behavior with -emit-extension-block-symbols mode enabled
Bugfixes:
- fixes a bug where some conformsTo relationships implicated by the conformances
declared on an extension to an external type were not emitted
(see test/SymbolGraph/Relationships/ConformsTo/Indirect.swift)
Further changes:
- documents the strategy for naming and associating children declared in extensions
to typealiases (see test/SymbolGraph/Relationships/MemberOf/Typealias.swift,
test/SymbolGraph/Symbols/Names.swift)
* only include the given symbol for qualified imports
rdar://96309088
* re-exporting one type should not allow unrelated types to sneak in
* ensure that children of re-exported types are also re-exported
When emitting a symbol graph file for a module that import modules via
`@_exported import`, emits those modules' symbols as well.
SR-15753
rdar://89547374
Consider declarations inside `@_spi` extensions to be internal.
Clean up the "implicitly private" check to work for `Decl` and not just
`ValueDecl`, allowing it to be used directly on extensions instead of having to
look for extensions everywhere.
rdar://63361634
This was just using `hasUnderscoredNaming` before but this only checks the
leafmost type. When filtering extended types, it should continue to look up
through nesting types to see if they are also implicitly private.
rdar://61843516
When extending another module's type in your module, serialize declarations in
the extension into the other module's "extension" symbol graph file, including
relationships. This mechanic should continue up to the rootmost module. For
example:
A.AStruct <- B.BStruct < C.CStruct
Both BStruct and CStruct should go in `@A` symbol graph files because AStruct
owns BStruct and by extension owns CStruct. This is reflected in
documentation curation in some form already.
rdar://60796811
Symbol graph files are processed per platform--documentation for symbols that
are unconditionally unavailable or obsoleted on a platform shouldn't be shown
for that same platform.
Also, removes `isUnconditionallyUnavailable` from the JSON format. If it's
unconditionally unavailable, it won't show up at all.
rdar://60193675
Requirements on extensions were only being gathered indirectly. This adds a new
optional field to `conformsTo` relationship edges, `swiftConstraints`, which
provides the requirements there.
rdar://60091161
Emit copies of default implementations in protocol extensions and superclass declarations in conforming types and subclasses respectively using a virtual USR, i.e. `${REAL_USR}::SYNTHESIZED::${CONFORMING_OR_SUBCLASS_TYPE_USR}`.
- Add a -skip-synthesized-members option to skip these synthesized members.
- Create a new wrapping `Symbol` type that can also contain a base type declaration as well as the inherited declaration for those synthesized cases. Move some symbol-specific APIs there.
- Doc comments can “cascade” down to protocol extensions or refinements in concrete types. When emitting the doc comment for a symbol, look up through to superclasses or protocol requirements for where a doc comment is actually written.
- Clean up filtering of implicitly private (e.g. “public underscored”) types
rdar://problem/59128787
When a module extends a type from another module, serialize those symbols into
separated files dedicated to those extended modules. This makes it easier to
ingest and categorize those symbols under the extended module if desired.
rdar://58941718
Up to now, the `SymbolGraphASTWalker` was only concerned with one module. This
change prepares for emitting multiple symbol graph files, for each module that
the module of interest extended. There is only one walker, so extract the
symbol logic into `SymbolGraph`, where it can be reused.
rdar://58941718
`pathComponents` doesn't help with disambiguation, so it shouldn't be a part of
the identifier, but can be moved up one level. Include an interface language in
the identifier instead.
rdar://problem/58853310
Adds a tool `swift-symbolgraph-extract` that reads an existing Swift
module and prints a platform- and language-agnostic JSON description of
the module, primarly for documentation.
Adds a small sub-library `SymbolGraphGen` which houses the core
implementation for collecting relevant information about declarations.
The main entry point is integrated directly into the driver as a mode:
the tool is meant to be run outside of the normal edit-compile-run/test
workflow to avoid impacting build times.
Along with common options for other tools, unique options include
`pretty-print` for debugging, and a `minimum-access-level` options for
including internal documentation.
A symbol graph is a directed graph where the nodes are symbols in a
module and the edges are relationships between them. For example, a
`struct S` may have a member `var x`. The graph would have two nodes for
`S` and `x`, and one "member-of" relationship edge. Other relationship
kinds include "inherits-from" or "conforms to". The data format for a
symbol graph is still under development and may change without notice
until a specificiation and versioning scheme is published.
Various aspects about a symbol are recorded in the nodes, such as
availability, documentation comments, or data needed for printing the
shapes of declarations without having to understand specifics about the
langauge.
Implicit and public-underscored stdlib declarations are not included by
default.
rdar://problem/55346798