Skip to content

Commit 94fead4

Browse files
committed
swift-api-extract: extract decls with @_spi_available attributes as SPI
Working similarly as SPI_AVAILABLE in Clang, Swift decls marked with @_spi_available should be considered private
1 parent 155eee3 commit 94fead4

File tree

2 files changed

+24
-2
lines changed

2 files changed

+24
-2
lines changed

lib/TBDGen/TBDGen.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1354,6 +1354,10 @@ void swift::writeTBDFile(ModuleDecl *M, llvm::raw_ostream &os,
13541354
}
13551355

13561356
class APIGenRecorder final : public APIRecorder {
1357+
bool isSPI(const ValueDecl* VD) {
1358+
assert(VD);
1359+
return VD->isSPI() || VD->isAvailableAsSPI();
1360+
}
13571361
public:
13581362
APIGenRecorder(apigen::API &api, ModuleDecl *module)
13591363
: api(api), module(module) {
@@ -1373,13 +1377,13 @@ class APIGenRecorder final : public APIRecorder {
13731377
auto ref = source.getSILDeclRef();
13741378
if (ref.hasDecl()) {
13751379
availability = getAvailability(ref.getDecl());
1376-
if (ref.getDecl()->isSPI())
1380+
if (isSPI(ref.getDecl()))
13771381
access = apigen::APIAccess::Private;
13781382
}
13791383
} else if (source.kind == SymbolSource::Kind::IR) {
13801384
auto ref = source.getIRLinkEntity();
13811385
if (ref.hasDecl()) {
1382-
if (ref.getDecl()->isSPI())
1386+
if (isSPI(ref.getDecl()))
13831387
access = apigen::APIAccess::Private;
13841388
}
13851389
}

test/APIJSON/spi.swift

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@ public class MyClass2 : NSObject {
1717
@_spi(Experimental) @objc public func spiMethod() {}
1818
}
1919

20+
@_spi_available(macOS 10.10, tvOS 14.0, *)
21+
@available(iOS 8.0, *)
22+
public func spiAvailableFunc() {}
23+
2024
// CHECK: {
2125
// CHECK-NEXT: "target":
2226
// CHECK-NEXT: "globals": [
@@ -63,6 +67,13 @@ public class MyClass2 : NSObject {
6367
// CHECK-NEXT: "linkage": "exported"
6468
// CHECK-NEXT: },
6569
// CHECK-NEXT: {
70+
// CHECK-NEXT: "name": "_$s8MyModule16spiAvailableFuncyyF",
71+
// CHECK-NEXT: "access": "public",
72+
// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface",
73+
// CHECK-NEXT: "linkage": "exported",
74+
// CHECK-NEXT: "unavailable": true
75+
// CHECK-NEXT: },
76+
// CHECK-NEXT: {
6677
// CHECK-NEXT: "name": "_OBJC_CLASS_$__TtC8MyModule8MyClass2",
6778
// CHECK-NEXT: "access": "public",
6879
// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface",
@@ -225,6 +236,13 @@ public class MyClass2 : NSObject {
225236
// CHECK-SPI-NEXT: "file": "/@input/MyModule.swiftmodule",
226237
// CHECK-SPI-NEXT: "linkage": "exported"
227238
// CHECK-SPI-NEXT: },
239+
// CHECK-SPI-NEXT: {
240+
// CHECK-SPI-NEXT: "name": "_$s8MyModule16spiAvailableFuncyyF",
241+
// CHECK-SPI-NEXT: "access": "private",
242+
// CHECK-SPI-NEXT: "file": "/@input/MyModule.swiftmodule",
243+
// CHECK-SPI-NEXT: "linkage": "exported",
244+
// CHECK-SPI-NEXT: "introduced": "10.10"
245+
// CHECK-SPI-NEXT: },
228246
// CHECK-SPI-NEXT: {
229247
// CHECK-SPI-NEXT: "name": "_OBJC_CLASS_$__TtC8MyModule7MyClass",
230248
// CHECK-SPI-NEXT: "access": "private",

0 commit comments

Comments
 (0)