mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
only recurse public-private type aliases from Clang (#79996)
rdar://145980187
This commit is contained in:
@@ -335,6 +335,9 @@ bool SymbolGraphASTWalker::walkToDeclPre(Decl *D, CharSourceRange Range) {
|
||||
}
|
||||
}
|
||||
|
||||
// If this is a Clang typedef of an underlying type that is being hidden (e.g. `typedef struct
|
||||
// _MyStruct { ... } MyStruct`) then copy in the child symbols from the underlying type to the
|
||||
// type alias.
|
||||
if (const auto *TD = dyn_cast_or_null<TypeAliasDecl>(VD)) {
|
||||
const auto InnerType = TD->getUnderlyingType();
|
||||
if (NominalTypeDecl *NTD = InnerType->getAnyNominal()) {
|
||||
@@ -342,8 +345,18 @@ bool SymbolGraphASTWalker::walkToDeclPre(Decl *D, CharSourceRange Range) {
|
||||
// otherwise isn't being shown
|
||||
if (isOurModule(NTD->getModuleContext()) &&
|
||||
!SG->canIncludeDeclAsNode(NTD)) {
|
||||
PublicPrivateTypeAliases.insert_or_assign(NTD, TD);
|
||||
synthesizeChildSymbols(NTD, TD);
|
||||
// We specifically only want to look for underlying types that are "embedded" in the typedef
|
||||
// definition, so let's pull out the Clang decl and check for that
|
||||
if (NTD->hasClangNode()) {
|
||||
if (const auto *ClangDecl = NTD->getClangNode().getAsDecl()) {
|
||||
if (const auto *ClangTagDecl = dyn_cast<clang::TagDecl>(ClangDecl)) {
|
||||
if (ClangTagDecl->isEmbeddedInDeclarator()) {
|
||||
PublicPrivateTypeAliases.insert_or_assign(NTD, TD);
|
||||
synthesizeChildSymbols(NTD, TD);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,21 +10,7 @@
|
||||
// _InnerType's type name should only appear in quotes like this once, in the declaration for OuterType
|
||||
// INNER-COUNT-1: "_InnerType"
|
||||
|
||||
// _InnerType.someFunc() as synthesized on OuterType
|
||||
// CHECK-DAG: "precise": "s:15HiddenTypeAlias06_InnerB0C8someFuncyyF::SYNTHESIZED::s:15HiddenTypeAlias05OuterB0a"
|
||||
|
||||
// someFunc is a member of OuterType
|
||||
// CHECK-DAG: "kind": "memberOf",{{[[:space:]]*}}"source": "s:15HiddenTypeAlias06_InnerB0C8someFuncyyF::SYNTHESIZED::s:15HiddenTypeAlias05OuterB0a",{{[[:space:]]*}}"target": "s:15HiddenTypeAlias05OuterB0a"
|
||||
|
||||
// OuterType conforms to SomeProtocol
|
||||
// CHECK-DAG: "kind": "conformsTo",{{[[:space:]]*}}"source": "s:15HiddenTypeAlias05OuterB0a",{{[[:space:]]*}}"target": "s:15HiddenTypeAlias12SomeProtocolP"
|
||||
|
||||
// OuterType "inherits from" BaseType
|
||||
// CHECK-DAG: "kind": "inheritsFrom",{{[[:space:]]*}}"source": "s:15HiddenTypeAlias05OuterB0a",{{[[:space:]]*}}"target": "s:15HiddenTypeAlias04BaseB0C"
|
||||
|
||||
// bonusFunc as a synthesized member of OuterType
|
||||
// CHECK-DAG: "precise": "s:15HiddenTypeAlias12SomeProtocolPAAE9bonusFuncyyF::SYNTHESIZED::s:15HiddenTypeAlias05OuterB0a",
|
||||
// CHECK-DAG: "kind": "memberOf",{{[[:space:]]*}}"source": "s:15HiddenTypeAlias12SomeProtocolPAAE9bonusFuncyyF::SYNTHESIZED::s:15HiddenTypeAlias05OuterB0a",{{[[:space:]]*}}"target": "s:15HiddenTypeAlias05OuterB0a",
|
||||
// CHECK-NOT: someFunc
|
||||
|
||||
public protocol SomeProtocol {}
|
||||
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
// RUN: %empty-directory(%t)
|
||||
// RUN: %target-build-swift %s -module-name HiddenTypeAliasRecursive -emit-module -emit-module-path %t/
|
||||
// RUN: %target-swift-symbolgraph-extract -module-name HiddenTypeAliasRecursive -I %t -pretty-print -output-dir %t -v
|
||||
// RUN: %FileCheck %s --input-file %t/HiddenTypeAliasRecursive.symbols.json
|
||||
|
||||
// Ensure that mutually-recursive public-private type aliases don't cause infinite recursion in
|
||||
// SymbolGraphGen when generating symbol graphs. (rdar://145980187)
|
||||
|
||||
// HiddenClassB is not referenced by any public symbol, so it shouldn't appear in any symbol graph
|
||||
// CHECK-NOT: HiddenClassB
|
||||
|
||||
// HiddenClassA should only appear one time: in the declaration for PublicAlias
|
||||
// CHECK-COUNT-1: HiddenClassA
|
||||
// CHECK-NOT: HiddenClassA
|
||||
|
||||
@_documentation(visibility: private)
|
||||
public class HiddenClassA {
|
||||
public typealias ProblematicA = HiddenClassB
|
||||
public func funcA() {}
|
||||
}
|
||||
|
||||
@_documentation(visibility: private)
|
||||
public class HiddenClassB {
|
||||
public typealias ProblematicB = HiddenClassA
|
||||
public func funcB() {}
|
||||
}
|
||||
|
||||
public typealias PublicAlias = HiddenClassA
|
||||
Reference in New Issue
Block a user