Skip to content

Commit 9ad0094

Browse files
author
Harlan Haskins
authored
Merge pull request swiftlang#22199 from harlanhaskins/type-extensionality
[api-digester] Don’t synthesize type nodes with no public members or conformances
2 parents 5da7001 + 081b05a commit 9ad0094

File tree

4 files changed

+62
-1
lines changed

4 files changed

+62
-1
lines changed

test/api-digester/Outputs/stability-stdlib-abi.swift.expected

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
Func _SmallString.computeIsASCII() has been removed
22
Func _SmallString.withMutableCapacity(_:) has been removed
33
Struct _StringObject.Discriminator has been removed
4+
Struct __swift_stdlib_UErrorCode has been removed
45
Var _SmallString.discriminator has been removed
56
Var _StringObject.CountAndFlags._storage has declared type change from UInt to UInt64
67
Var _StringObject.CountAndFlags.countMask has declared type change from UInt to UInt64
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// RUN: %empty-directory(%t.mod)
2+
// RUN: %empty-directory(%t.sdk)
3+
// RUN: %empty-directory(%t.module-cache)
4+
// RUN: %swift -emit-module -o %t.mod/cake.swiftmodule %S/Inputs/cake.swift -parse-as-library -I %S/Inputs/ClangCake %clang-importer-sdk-nosource
5+
// RUN: %swift -emit-module -o %t.mod/main.swiftmodule %s -parse-as-library -I %t.mod -I %S/Inputs/ClangCake %clang-importer-sdk-nosource
6+
// RUN: %api-digester -dump-sdk -module main -o %t.dump.json -module-cache-path %t.module-cache -swift-only -I %t.mod -I %S/Inputs/ClangCake %clang-importer-sdk-nosource
7+
// RUN: %FileCheck %s < %t.dump.json
8+
9+
import cake
10+
11+
// CHECK: publicSymbol
12+
public func publicSymbol() {}
13+
14+
internal protocol InternalProto {}
15+
public protocol PublicProto {}
16+
17+
// This internal extension doesn't declare any new members on S1, so it
18+
// shouldn't show up at all in the output.
19+
// CHECK-NOT: S1
20+
internal extension S1 {
21+
var x: Int { return 4 }
22+
}
23+
24+
// There should only be one conformance declared: the conformance of C0 to
25+
// PublicProto. InternalProto should not show up in the list.
26+
// CHECK: "name": "C0",
27+
// CHECK: "conformances": [
28+
// CHECK-NEXT: {
29+
// CHECK-NEXT: "kind": "Conformance",
30+
// CHECK-NEXT: "name": "PublicProto",
31+
// CHECK-NEXT: "printedName": "PublicProto"
32+
// CHECK-NEXT: }
33+
// CHECK-NEXT: ]
34+
extension C0: InternalProto {
35+
}
36+
extension C0: PublicProto {
37+
}

tools/swift-api-digester/ModuleAnalyzerNodes.cpp

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1368,11 +1368,31 @@ SwiftDeclCollector::constructExternalExtensionNode(NominalTypeDecl *NTD,
13681368
ArrayRef<ExtensionDecl*> AllExts) {
13691369
auto *TypeNode = SDKNodeInitInfo(Ctx, NTD).createSDKNode(SDKNodeKind::DeclType);
13701370
addConformancesToTypeDecl(cast<SDKNodeDeclType>(TypeNode), NTD);
1371+
1372+
bool anyConformancesAdded = false;
13711373
// The members of the extensions are the only members of this synthesized type.
13721374
for (auto *Ext: AllExts) {
13731375
HandledExtensions.insert(Ext);
13741376
addMembersToRoot(TypeNode, Ext);
1377+
1378+
// Keep track if we've declared any conformances in this extension.
1379+
// FIXME: This is too conservative. We only _really_ care if this extension
1380+
// declares a conformance to any public protocols outside the module
1381+
// where the extended type originated. Eventually this should be
1382+
// updated to filter extensions that declare conformances to internal
1383+
// protocols that either don't inherit from any protocols or only
1384+
// inherit from other internal protocols. It should also consider
1385+
// conditional conformances with internal requirements that are still
1386+
// part of the ABI.
1387+
if (!Ext->getInherited().empty())
1388+
anyConformancesAdded = true;
13751389
}
1390+
1391+
// If none of the extensions added any public members or conformances, don't
1392+
// synthesize the type node.
1393+
if (TypeNode->getChildrenCount() == 0 && !anyConformancesAdded)
1394+
return nullptr;
1395+
13761396
return TypeNode;
13771397
}
13781398

@@ -1532,7 +1552,8 @@ void SwiftDeclCollector::lookupVisibleDecls(ArrayRef<ModuleDecl *> Modules) {
15321552
}
15331553
}
15341554
for (auto Pair: ExtensionMap) {
1535-
RootNode->addChild(constructExternalExtensionNode(Pair.first, Pair.second));
1555+
if (auto child = constructExternalExtensionNode(Pair.first, Pair.second))
1556+
RootNode->addChild(child);
15361557
}
15371558
}
15381559

tools/swift-api-digester/ModuleAnalyzerNodes.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -648,6 +648,8 @@ class SwiftDeclCollector: public VisibleDeclConsumer {
648648

649649
void printTopLevelNames();
650650

651+
/// Adds all conformances from the provided NominalTypeDecl to the provided
652+
/// SDK node for that type decl.
651653
void addConformancesToTypeDecl(SDKNodeDeclType *Root, NominalTypeDecl* NTD);
652654
void addMembersToRoot(SDKNode *Root, IterableDeclContext *Context);
653655

0 commit comments

Comments
 (0)