From 278b4fbdce4f731f9881a6fba1cf403c4ca6cf4c Mon Sep 17 00:00:00 2001 From: Zixu Wang Date: Tue, 21 Oct 2025 11:05:34 -0700 Subject: [PATCH] [APIGen] Handle SPI availability for nested decls - Add SPI availability information to `APIAvailability` from attribute `@_spi_available`. - Correctly obtain effective availability for nested declarations without immediate availability attributes. Resolves rdar://159702280 --- lib/IRGen/APIGen.cpp | 2 + lib/IRGen/APIGen.h | 4 +- lib/IRGen/TBDGen.cpp | 18 +- test/APIJSON/apigen.swift | 70 +++-- test/APIJSON/availability.swift | 99 ++++++- test/APIJSON/spi.swift | 479 +++++++++++++++----------------- test/APIJSON/struct.swift | 3 +- 7 files changed, 381 insertions(+), 294 deletions(-) diff --git a/lib/IRGen/APIGen.cpp b/lib/IRGen/APIGen.cpp index 93dbe52f61a24..b2acc8f27921c 100644 --- a/lib/IRGen/APIGen.cpp +++ b/lib/IRGen/APIGen.cpp @@ -84,6 +84,8 @@ static void serialize(llvm::json::OStream &OS, APIAvailability availability) { OS.attribute("obsoleted", availability.obsoleted); if (availability.unavailable) OS.attribute("unavailable", availability.unavailable); + if (availability.spiAvailable) + OS.attribute("SPIAvailable", availability.spiAvailable); } static void serialize(llvm::json::OStream &OS, APILinkage linkage) { diff --git a/lib/IRGen/APIGen.h b/lib/IRGen/APIGen.h index 891d7b9228098..11b320049f102 100644 --- a/lib/IRGen/APIGen.h +++ b/lib/IRGen/APIGen.h @@ -72,9 +72,11 @@ struct APIAvailability { std::string introduced; std::string obsoleted; bool unavailable = false; + bool spiAvailable = false; bool empty() { - return introduced.empty() && obsoleted.empty() && !unavailable; + return introduced.empty() && obsoleted.empty() && !unavailable && + !spiAvailable; } }; diff --git a/lib/IRGen/TBDGen.cpp b/lib/IRGen/TBDGen.cpp index cb8a74c810a0d..d4ee8c05dcbfd 100644 --- a/lib/IRGen/TBDGen.cpp +++ b/lib/IRGen/TBDGen.cpp @@ -686,7 +686,7 @@ void swift::writeTBDFile(ModuleDecl *M, llvm::raw_ostream &os, } class APIGenRecorder final : public APIRecorder { - static bool isSPI(const Decl *decl) { + bool isSPI(const Decl *decl) { assert(decl); if (auto value = dyn_cast(decl)) { @@ -700,7 +700,7 @@ class APIGenRecorder final : public APIRecorder { return true; } - return decl->isSPI() || decl->isAvailableAsSPI(); + return decl->isSPI() || getAvailability(decl).spiAvailable; } public: @@ -805,25 +805,31 @@ class APIGenRecorder final : public APIRecorder { llvm::DenseMap CategoryCounts; apigen::APIAvailability getAvailability(const Decl *decl) { - std::optional unavailable; + std::optional unavailable, spiAvailable; std::string introduced, obsoleted; - bool hasFallbackUnavailability = false; + bool hasFallbackUnavailability = false, hasFallbackSPIAvailability = false; auto platform = targetPlatform(module->getASTContext().LangOpts); - for (auto attr : decl->getSemanticAvailableAttrs()) { + const Decl *declForAvailability = decl->getInnermostDeclWithAvailability(); + if (!declForAvailability) + return {}; + for (auto attr : declForAvailability->getSemanticAvailableAttrs()) { if (!attr.isPlatformSpecific()) { hasFallbackUnavailability = attr.isUnconditionallyUnavailable(); + hasFallbackSPIAvailability = attr.isSPI(); continue; } if (attr.getPlatform() != platform) continue; unavailable = attr.isUnconditionallyUnavailable(); + spiAvailable = attr.isSPI(); if (attr.getIntroduced()) introduced = attr.getIntroduced()->getAsString(); if (attr.getObsoleted()) obsoleted = attr.getObsoleted()->getAsString(); } return {introduced, obsoleted, - unavailable.value_or(hasFallbackUnavailability)}; + unavailable.value_or(hasFallbackUnavailability), + spiAvailable.value_or(hasFallbackSPIAvailability)}; } StringRef getSelectorName(SILDeclRef method, SmallString<128> &buffer) { diff --git a/test/APIJSON/apigen.swift b/test/APIJSON/apigen.swift index b8f68b03132d2..ca86632b35c00 100644 --- a/test/APIJSON/apigen.swift +++ b/test/APIJSON/apigen.swift @@ -127,13 +127,15 @@ public var myGlobalVar: Int = 42 // CHECK-NEXT: "name": "_$s8MyModule4TestC7method1yyFTj", // CHECK-NEXT: "access": "public", // CHECK-NEXT: "file": "SOURCE_DIR/test/APIJSON/apigen.swift", -// CHECK-NEXT: "linkage": "exported" +// CHECK-NEXT: "linkage": "exported", +// CHECK-NEXT: "introduced": "10.13" // CHECK-NEXT: }, // CHECK-NEXT: { // CHECK-NEXT: "name": "_$s8MyModule4TestC7method1yyFTq", // CHECK-NEXT: "access": "public", // CHECK-NEXT: "file": "SOURCE_DIR/test/APIJSON/apigen.swift", // CHECK-NEXT: "linkage": "exported" +// CHECK-NEXT: "introduced": "10.13" // CHECK-NEXT: }, // CHECK-NEXT: { // CHECK-NEXT: "name": "_$s8MyModule4TestC7method2yyFZTj", @@ -153,25 +155,29 @@ public var myGlobalVar: Int = 42 // CHECK-NEXT: "name": "_$s8MyModule4TestC7nonObjcyyFTj", // CHECK-NEXT: "access": "public", // CHECK-NEXT: "file": "SOURCE_DIR/test/APIJSON/apigen.swift", -// CHECK-NEXT: "linkage": "exported" +// CHECK-NEXT: "linkage": "exported", +// CHECK-NEXT: "introduced": "10.13" // CHECK-NEXT: }, // CHECK-NEXT: { // CHECK-NEXT: "name": "_$s8MyModule4TestC7nonObjcyyFTq", // CHECK-NEXT: "access": "public", // CHECK-NEXT: "file": "SOURCE_DIR/test/APIJSON/apigen.swift", -// CHECK-NEXT: "linkage": "exported" +// CHECK-NEXT: "linkage": "exported", +// CHECK-NEXT: "introduced": "10.13" // CHECK-NEXT: }, // CHECK-NEXT: { // CHECK-NEXT: "name": "_$s8MyModule4TestCACycfC", // CHECK-NEXT: "access": "public", // CHECK-NEXT: "file": "SOURCE_DIR/test/APIJSON/apigen.swift", -// CHECK-NEXT: "linkage": "exported" +// CHECK-NEXT: "linkage": "exported", +// CHECK-NEXT: "introduced": "10.13" // CHECK-NEXT: }, // CHECK-NEXT: { // CHECK-NEXT: "name": "_$s8MyModule4TestCACycfc", // CHECK-NEXT: "access": "public", // CHECK-NEXT: "file": "SOURCE_DIR/test/APIJSON/apigen.swift", -// CHECK-NEXT: "linkage": "exported" +// CHECK-NEXT: "linkage": "exported", +// CHECK-NEXT: "introduced": "10.13" // CHECK-NEXT: }, // CHECK-NEXT: { // CHECK-NEXT: "name": "_$s8MyModule4TestCMa", @@ -212,7 +218,8 @@ public var myGlobalVar: Int = 42 // CHECK-NEXT: "name": "_$s8MyModule4TestCfD", // CHECK-NEXT: "access": "public", // CHECK-NEXT: "file": "SOURCE_DIR/test/APIJSON/apigen.swift", -// CHECK-NEXT: "linkage": "exported" +// CHECK-NEXT: "linkage": "exported", +// CHECK-NEXT: "introduced": "10.13" // CHECK-NEXT: }, // CHECK-NEXT: { // CHECK-NEXT: "name": "_$s8MyModule5Test2CMa", @@ -350,31 +357,36 @@ public var myGlobalVar: Int = 42 // CHECK-NEXT: "name": "_$s8MyModule7DerivedC15inheritlyPublicyyF", // CHECK-NEXT: "access": "public", // CHECK-NEXT: "file": "SOURCE_DIR/test/APIJSON/apigen.swift", -// CHECK-NEXT: "linkage": "exported" +// CHECK-NEXT: "linkage": "exported", +// CHECK-NEXT: "introduced": "10.13" // CHECK-NEXT: }, // CHECK-NEXT: { // CHECK-NEXT: "name": "_$s8MyModule7DerivedC8readOnlyACSi_tcfC", // CHECK-NEXT: "access": "private", // CHECK-NEXT: "file": "SOURCE_DIR/test/APIJSON/apigen.swift", -// CHECK-NEXT: "linkage": "exported" +// CHECK-NEXT: "linkage": "exported", +// CHECK-NEXT: "introduced": "10.13" // CHECK-NEXT: }, // CHECK-NEXT: { // CHECK-NEXT: "name": "_$s8MyModule7DerivedC8readOnlyACSi_tcfCTj", // CHECK-NEXT: "access": "private", // CHECK-NEXT: "file": "SOURCE_DIR/test/APIJSON/apigen.swift", -// CHECK-NEXT: "linkage": "exported" +// CHECK-NEXT: "linkage": "exported", +// CHECK-NEXT: "introduced": "10.13" // CHECK-NEXT: }, // CHECK-NEXT: { // CHECK-NEXT: "name": "_$s8MyModule7DerivedC8readOnlyACSi_tcfCTq", // CHECK-NEXT: "access": "private", // CHECK-NEXT: "file": "SOURCE_DIR/test/APIJSON/apigen.swift", -// CHECK-NEXT: "linkage": "exported" +// CHECK-NEXT: "linkage": "exported", +// CHECK-NEXT: "introduced": "10.13" // CHECK-NEXT: }, // CHECK-NEXT: { // CHECK-NEXT: "name": "_$s8MyModule7DerivedC8readOnlyACSi_tcfc", // CHECK-NEXT: "access": "private", // CHECK-NEXT: "file": "SOURCE_DIR/test/APIJSON/apigen.swift", -// CHECK-NEXT: "linkage": "exported" +// CHECK-NEXT: "linkage": "exported", +// CHECK-NEXT: "introduced": "10.13" // CHECK-NEXT: }, // CHECK-NEXT: { // CHECK-NEXT: "name": "_$s8MyModule7DerivedC8readOnlySivMTj", @@ -394,43 +406,50 @@ public var myGlobalVar: Int = 42 // CHECK-NEXT: "name": "_$s8MyModule7DerivedC8readOnlySivgTj", // CHECK-NEXT: "access": "public", // CHECK-NEXT: "file": "SOURCE_DIR/test/APIJSON/apigen.swift", -// CHECK-NEXT: "linkage": "exported" +// CHECK-NEXT: "linkage": "exported", +// CHECK-NEXT: "introduced": "10.13" // CHECK-NEXT: }, // CHECK-NEXT: { // CHECK-NEXT: "name": "_$s8MyModule7DerivedC8readOnlySivgTq", // CHECK-NEXT: "access": "public", // CHECK-NEXT: "file": "SOURCE_DIR/test/APIJSON/apigen.swift", -// CHECK-NEXT: "linkage": "exported" +// CHECK-NEXT: "linkage": "exported", +// CHECK-NEXT: "introduced": "10.13" // CHECK-NEXT: }, // CHECK-NEXT: { // CHECK-NEXT: "name": "_$s8MyModule7DerivedC8readOnlySivpMV", // CHECK-NEXT: "access": "public", // CHECK-NEXT: "file": "SOURCE_DIR/test/APIJSON/apigen.swift", -// CHECK-NEXT: "linkage": "exported" +// CHECK-NEXT: "linkage": "exported", +// CHECK-NEXT: "introduced": "10.13" // CHECK-NEXT: }, // CHECK-NEXT: { // CHECK-NEXT: "name": "_$s8MyModule7DerivedC8readOnlySivsTj", // CHECK-NEXT: "access": "private", // CHECK-NEXT: "file": "SOURCE_DIR/test/APIJSON/apigen.swift", -// CHECK-NEXT: "linkage": "exported" +// CHECK-NEXT: "linkage": "exported", +// CHECK-NEXT: "introduced": "10.13" // CHECK-NEXT: }, // CHECK-NEXT: { // CHECK-NEXT: "name": "_$s8MyModule7DerivedC8readOnlySivsTq", // CHECK-NEXT: "access": "private", // CHECK-NEXT: "file": "SOURCE_DIR/test/APIJSON/apigen.swift", -// CHECK-NEXT: "linkage": "exported" +// CHECK-NEXT: "linkage": "exported", +// CHECK-NEXT: "introduced": "10.13" // CHECK-NEXT: }, // CHECK-NEXT: { // CHECK-NEXT: "name": "_$s8MyModule7DerivedCACycfC", // CHECK-NEXT: "access": "public", // CHECK-NEXT: "file": "SOURCE_DIR/test/APIJSON/apigen.swift", -// CHECK-NEXT: "linkage": "exported" +// CHECK-NEXT: "linkage": "exported", +// CHECK-NEXT: "introduced": "10.13" // CHECK-NEXT: }, // CHECK-NEXT: { // CHECK-NEXT: "name": "_$s8MyModule7DerivedCACycfc", // CHECK-NEXT: "access": "public", // CHECK-NEXT: "file": "SOURCE_DIR/test/APIJSON/apigen.swift", -// CHECK-NEXT: "linkage": "exported" +// CHECK-NEXT: "linkage": "exported", +// CHECK-NEXT: "introduced": "10.13" // CHECK-NEXT: }, // CHECK-NEXT: { // CHECK-NEXT: "name": "_$s8MyModule7DerivedCMa", @@ -471,7 +490,8 @@ public var myGlobalVar: Int = 42 // CHECK-NEXT: "name": "_$s8MyModule7DerivedCfD", // CHECK-NEXT: "access": "public", // CHECK-NEXT: "file": "SOURCE_DIR/test/APIJSON/apigen.swift", -// CHECK-NEXT: "linkage": "exported" +// CHECK-NEXT: "linkage": "exported", +// CHECK-NEXT: "introduced": "10.13" // CHECK-NEXT: } // CHECK-NEXT: ], // CHECK-NEXT: "interfaces": [ @@ -486,12 +506,14 @@ public var myGlobalVar: Int = 42 // CHECK-NEXT: { // CHECK-NEXT: "name": "method1", // CHECK-NEXT: "access": "public", -// CHECK-NEXT: "file": "SOURCE_DIR/test/APIJSON/apigen.swift" +// CHECK-NEXT: "file": "SOURCE_DIR/test/APIJSON/apigen.swift", +// CHECK-NEXT: "introduced": "10.13" // CHECK-NEXT: }, // CHECK-NEXT: { // CHECK-NEXT: "name": "init", // CHECK-NEXT: "access": "public", -// CHECK-NEXT: "file": "SOURCE_DIR/test/APIJSON/apigen.swift" +// CHECK-NEXT: "file": "SOURCE_DIR/test/APIJSON/apigen.swift", +// CHECK-NEXT: "introduced": "10.13" // CHECK-NEXT: } // CHECK-NEXT: ], // CHECK-NEXT: "classMethods": [ @@ -539,12 +561,14 @@ public var myGlobalVar: Int = 42 // CHECK-NEXT: { // CHECK-NEXT: "name": "method1", // CHECK-NEXT: "access": "public", -// CHECK-NEXT: "file": "SOURCE_DIR/test/APIJSON/apigen.swift" +// CHECK-NEXT: "file": "SOURCE_DIR/test/APIJSON/apigen.swift", +// CHECK-NEXT: "introduced": "10.13" // CHECK-NEXT: }, // CHECK-NEXT: { // CHECK-NEXT: "name": "init", // CHECK-NEXT: "access": "public", -// CHECK-NEXT: "file": "SOURCE_DIR/test/APIJSON/apigen.swift" +// CHECK-NEXT: "file": "SOURCE_DIR/test/APIJSON/apigen.swift", +// CHECK-NEXT: "introduced": "10.13" // CHECK-NEXT: } // CHECK-NEXT: ], // CHECK-NEXT: "classMethods": [] diff --git a/test/APIJSON/availability.swift b/test/APIJSON/availability.swift index f55689d651adb..57124cae8d6b3 100644 --- a/test/APIJSON/availability.swift +++ b/test/APIJSON/availability.swift @@ -8,7 +8,14 @@ @available(macOS 10.10, *) @available(tvOS, unavailable) @available(watchOS 10.0, *) -public class A {} +public class A { + public func noAvailablilityAttr() {} +} + +@available(macOS, unavailable) +public class UnavailableClass { + public func noAvailablilityAttr() {} +} @available(*, unavailable) public func callUnavailable() {} @@ -39,6 +46,76 @@ extension A { // CHECK-NEXT: "unavailable": true // CHECK-NEXT: }, // CHECK-NEXT: { +// CHECK-NEXT: "name": "_$s8MyModule16UnavailableClassC19noAvailablilityAttryyFTj", +// CHECK-NEXT: "access": "public", +// CHECK-NEXT: "file": "SOURCE_DIR/test/APIJSON/availability.swift", +// CHECK-NEXT: "linkage": "exported", +// CHECK-NEXT: "unavailable": true +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "name": "_$s8MyModule16UnavailableClassC19noAvailablilityAttryyFTq", +// CHECK-NEXT: "access": "public", +// CHECK-NEXT: "file": "SOURCE_DIR/test/APIJSON/availability.swift", +// CHECK-NEXT: "linkage": "exported", +// CHECK-NEXT: "unavailable": true +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "name": "_$s8MyModule16UnavailableClassCMa", +// CHECK-NEXT: "access": "public", +// CHECK-NEXT: "file": "SOURCE_DIR/test/APIJSON/availability.swift", +// CHECK-NEXT: "linkage": "exported", +// CHECK-NEXT: "unavailable": true +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "name": "_$s8MyModule16UnavailableClassCMm", +// CHECK-NEXT: "access": "public", +// CHECK-NEXT: "file": "SOURCE_DIR/test/APIJSON/availability.swift", +// CHECK-NEXT: "linkage": "exported", +// CHECK-NEXT: "unavailable": true +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "name": "_$s8MyModule16UnavailableClassCMn", +// CHECK-NEXT: "access": "public", +// CHECK-NEXT: "file": "SOURCE_DIR/test/APIJSON/availability.swift", +// CHECK-NEXT: "linkage": "exported", +// CHECK-NEXT: "unavailable": true +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "name": "_$s8MyModule16UnavailableClassCMo", +// CHECK-NEXT: "access": "public", +// CHECK-NEXT: "file": "SOURCE_DIR/test/APIJSON/availability.swift", +// CHECK-NEXT: "linkage": "exported", +// CHECK-NEXT: "unavailable": true +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "name": "_$s8MyModule16UnavailableClassCMu", +// CHECK-NEXT: "access": "public", +// CHECK-NEXT: "file": "SOURCE_DIR/test/APIJSON/availability.swift", +// CHECK-NEXT: "linkage": "exported", +// CHECK-NEXT: "unavailable": true +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "name": "_$s8MyModule16UnavailableClassCN", +// CHECK-NEXT: "access": "public", +// CHECK-NEXT: "file": "SOURCE_DIR/test/APIJSON/availability.swift", +// CHECK-NEXT: "linkage": "exported", +// CHECK-NEXT: "unavailable": true +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "name": "_$s8MyModule16UnavailableClassCfD", +// CHECK-NEXT: "access": "public", +// CHECK-NEXT: "file": "SOURCE_DIR/test/APIJSON/availability.swift", +// CHECK-NEXT: "linkage": "exported", +// CHECK-NEXT: "unavailable": true +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "name": "_$s8MyModule16UnavailableClassCfd", +// CHECK-NEXT: "access": "public", +// CHECK-NEXT: "file": "SOURCE_DIR/test/APIJSON/availability.swift", +// CHECK-NEXT: "linkage": "exported", +// CHECK-NEXT: "unavailable": true +// CHECK-NEXT: }, +// CHECK-NEXT: { // CHECK-NEXT: "name": "_$s8MyModule1AC15getUnavailableAyyF", // CHECK-NEXT: "access": "public", // CHECK-NEXT: "file": "SOURCE_DIR/test/APIJSON/availability.swift", @@ -46,6 +123,20 @@ extension A { // CHECK-NEXT: "unavailable": true // CHECK-NEXT: }, // CHECK-NEXT: { +// CHECK-NEXT: "name": "_$s8MyModule1AC19noAvailablilityAttryyFTj", +// CHECK-NEXT: "access": "public", +// CHECK-NEXT: "file": "SOURCE_DIR/test/APIJSON/availability.swift", +// CHECK-NEXT: "linkage": "exported", +// CHECK-NEXT: "introduced": "10.10" +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "name": "_$s8MyModule1AC19noAvailablilityAttryyFTq", +// CHECK-NEXT: "access": "public", +// CHECK-NEXT: "file": "SOURCE_DIR/test/APIJSON/availability.swift", +// CHECK-NEXT: "linkage": "exported", +// CHECK-NEXT: "introduced": "10.10" +// CHECK-NEXT: }, +// CHECK-NEXT: { // CHECK-NEXT: "name": "_$s8MyModule1AC4getAyyF", // CHECK-NEXT: "access": "public", // CHECK-NEXT: "file": "SOURCE_DIR/test/APIJSON/availability.swift", @@ -98,13 +189,15 @@ extension A { // CHECK-NEXT: "name": "_$s8MyModule1ACfD", // CHECK-NEXT: "access": "public", // CHECK-NEXT: "file": "SOURCE_DIR/test/APIJSON/availability.swift", -// CHECK-NEXT: "linkage": "exported" +// CHECK-NEXT: "linkage": "exported", +// CHECK-NEXT: "introduced": "10.10" // CHECK-NEXT: }, // CHECK-NEXT: { // CHECK-NEXT: "name": "_$s8MyModule1ACfd", // CHECK-NEXT: "access": "public", // CHECK-NEXT: "file": "SOURCE_DIR/test/APIJSON/availability.swift", -// CHECK-NEXT: "linkage": "exported" +// CHECK-NEXT: "linkage": "exported", +// CHECK-NEXT: "introduced": "10.10" // CHECK-NEXT: }, // CHECK-NEXT: { // CHECK-NEXT: "name": "_$s8MyModule23availableOnlyOnActiveOSyyF", diff --git a/test/APIJSON/spi.swift b/test/APIJSON/spi.swift index fbde18fdcaa91..fd8b6c0af7f08 100644 --- a/test/APIJSON/spi.swift +++ b/test/APIJSON/spi.swift @@ -3,8 +3,8 @@ // RUN: %empty-directory(%t/ModuleCache) // RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk-nosource -I %t) %s -parse-as-library -emit-module -emit-module-path %t/MyModule.swiftmodule -enable-library-evolution -module-name MyModule -swift-version 5 -// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk-nosource -I %t) %s -parse-as-library -emit-module -emit-module-path %t/MyModule.swiftmodule -enable-library-evolution -module-name MyModule -swift-version 5 -emit-api-descriptor-path %t/api.json -// RUN: %validate-json %t/api.json | %FileCheck %s --check-prefixes=CHECK-SPI,CHECK-SPI-EMIT +// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk-nosource -I %t) %s -parse-as-library -emit-module -emit-module-path %t/MyModule.swiftmodule -enable-library-evolution -module-name MyModule -swift-version 5 -emit-api-descriptor-path %t/api.json -target arm64-apple-macos26 +// RUN: %validate-json %t/api.json | %FileCheck %s import Foundation @@ -25,336 +25,295 @@ public class MyClass2 : NSObject { @available(iOS 8.0, *) public func spiAvailableFunc() {} +@_spi_available(macOS 11, *) +@available(iOS 10, *) +public class SPIClass { + public func noAvailabilityAttr() {} +} + // CHECK: { -// CHECK-NEXT: "target": +// CHECK-NEXT: "target": "arm64-apple-macos26", // CHECK-NEXT: "globals": [ // CHECK-NEXT: { +// CHECK-NEXT: "name": "_$s8MyModule0A5ClassC9spiMethodyyFTj", +// CHECK-NEXT: "access": "private", +// CHECK-NEXT: "file": "SOURCE_DIR/test/APIJSON/spi.swift", +// CHECK-NEXT: "linkage": "exported" +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "name": "_$s8MyModule0A5ClassC9spiMethodyyFTq", +// CHECK-NEXT: "access": "private", +// CHECK-NEXT: "file": "SOURCE_DIR/test/APIJSON/spi.swift", +// CHECK-NEXT: "linkage": "exported" +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "name": "_$s8MyModule0A5ClassCACycfC", +// CHECK-NEXT: "access": "private", +// CHECK-NEXT: "file": "SOURCE_DIR/test/APIJSON/spi.swift", +// CHECK-NEXT: "linkage": "exported" +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "name": "_$s8MyModule0A5ClassCACycfc", +// CHECK-NEXT: "access": "private", +// CHECK-NEXT: "file": "SOURCE_DIR/test/APIJSON/spi.swift", +// CHECK-NEXT: "linkage": "exported" +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "name": "_$s8MyModule0A5ClassCMa", +// CHECK-NEXT: "access": "private", +// CHECK-NEXT: "file": "SOURCE_DIR/test/APIJSON/spi.swift", +// CHECK-NEXT: "linkage": "exported" +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "name": "_$s8MyModule0A5ClassCMn", +// CHECK-NEXT: "access": "private", +// CHECK-NEXT: "file": "SOURCE_DIR/test/APIJSON/spi.swift", +// CHECK-NEXT: "linkage": "exported" +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "name": "_$s8MyModule0A5ClassCMo", +// CHECK-NEXT: "access": "private", +// CHECK-NEXT: "file": "SOURCE_DIR/test/APIJSON/spi.swift", +// CHECK-NEXT: "linkage": "exported" +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "name": "_$s8MyModule0A5ClassCMu", +// CHECK-NEXT: "access": "private", +// CHECK-NEXT: "file": "SOURCE_DIR/test/APIJSON/spi.swift", +// CHECK-NEXT: "linkage": "exported" +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "name": "_$s8MyModule0A5ClassCN", +// CHECK-NEXT: "access": "private", +// CHECK-NEXT: "file": "SOURCE_DIR/test/APIJSON/spi.swift", +// CHECK-NEXT: "linkage": "exported" +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "name": "_$s8MyModule0A5ClassCfD", +// CHECK-NEXT: "access": "private", +// CHECK-NEXT: "file": "SOURCE_DIR/test/APIJSON/spi.swift", +// CHECK-NEXT: "linkage": "exported" +// CHECK-NEXT: }, +// CHECK-NEXT: { // CHECK-NEXT: "name": "_$s8MyModule0A6Class2C18spiAvailableMethodyyFTj", -// CHECK-NEXT: "access": "public", -// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-NEXT: "access": "private", +// CHECK-NEXT: "file": "SOURCE_DIR/test/APIJSON/spi.swift", // CHECK-NEXT: "linkage": "exported", -// CHECK-NEXT: "unavailable": true +// CHECK-NEXT: "introduced": "10.10", +// CHECK-NEXT: "SPIAvailable": true // CHECK-NEXT: }, // CHECK-NEXT: { // CHECK-NEXT: "name": "_$s8MyModule0A6Class2C18spiAvailableMethodyyFTq", -// CHECK-NEXT: "access": "public", -// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-NEXT: "access": "private", +// CHECK-NEXT: "file": "SOURCE_DIR/test/APIJSON/spi.swift", // CHECK-NEXT: "linkage": "exported", -// CHECK-NEXT: "unavailable": true +// CHECK-NEXT: "introduced": "10.10", +// CHECK-NEXT: "SPIAvailable": true +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "name": "_$s8MyModule0A6Class2C9spiMethodyyFTj", +// CHECK-NEXT: "access": "private", +// CHECK-NEXT: "file": "SOURCE_DIR/test/APIJSON/spi.swift", +// CHECK-NEXT: "linkage": "exported" +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "name": "_$s8MyModule0A6Class2C9spiMethodyyFTq", +// CHECK-NEXT: "access": "private", +// CHECK-NEXT: "file": "SOURCE_DIR/test/APIJSON/spi.swift", +// CHECK-NEXT: "linkage": "exported" // CHECK-NEXT: }, // CHECK-NEXT: { // CHECK-NEXT: "name": "_$s8MyModule0A6Class2CACycfC", // CHECK-NEXT: "access": "public", -// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-NEXT: "file": "SOURCE_DIR/test/APIJSON/spi.swift", // CHECK-NEXT: "linkage": "exported" // CHECK-NEXT: }, // CHECK-NEXT: { // CHECK-NEXT: "name": "_$s8MyModule0A6Class2CACycfc", // CHECK-NEXT: "access": "public", -// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-NEXT: "file": "SOURCE_DIR/test/APIJSON/spi.swift", // CHECK-NEXT: "linkage": "exported" // CHECK-NEXT: }, // CHECK-NEXT: { // CHECK-NEXT: "name": "_$s8MyModule0A6Class2CMa", // CHECK-NEXT: "access": "public", -// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-NEXT: "file": "SOURCE_DIR/test/APIJSON/spi.swift", // CHECK-NEXT: "linkage": "exported" // CHECK-NEXT: }, // CHECK-NEXT: { // CHECK-NEXT: "name": "_$s8MyModule0A6Class2CMn", // CHECK-NEXT: "access": "public", -// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-NEXT: "file": "SOURCE_DIR/test/APIJSON/spi.swift", // CHECK-NEXT: "linkage": "exported" // CHECK-NEXT: }, // CHECK-NEXT: { // CHECK-NEXT: "name": "_$s8MyModule0A6Class2CMo", // CHECK-NEXT: "access": "public", -// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-NEXT: "file": "SOURCE_DIR/test/APIJSON/spi.swift", // CHECK-NEXT: "linkage": "exported" // CHECK-NEXT: }, // CHECK-NEXT: { // CHECK-NEXT: "name": "_$s8MyModule0A6Class2CMu", // CHECK-NEXT: "access": "public", -// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-NEXT: "file": "SOURCE_DIR/test/APIJSON/spi.swift", // CHECK-NEXT: "linkage": "exported" // CHECK-NEXT: }, // CHECK-NEXT: { // CHECK-NEXT: "name": "_$s8MyModule0A6Class2CN", // CHECK-NEXT: "access": "public", -// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-NEXT: "file": "SOURCE_DIR/test/APIJSON/spi.swift", // CHECK-NEXT: "linkage": "exported" // CHECK-NEXT: }, // CHECK-NEXT: { // CHECK-NEXT: "name": "_$s8MyModule0A6Class2CfD", // CHECK-NEXT: "access": "public", -// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-NEXT: "file": "SOURCE_DIR/test/APIJSON/spi.swift", +// CHECK-NEXT: "linkage": "exported" +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "name": "_$s8MyModule15newUnprovenFuncyyF", +// CHECK-NEXT: "access": "private", +// CHECK-NEXT: "file": "SOURCE_DIR/test/APIJSON/spi.swift", // CHECK-NEXT: "linkage": "exported" // CHECK-NEXT: }, // CHECK-NEXT: { // CHECK-NEXT: "name": "_$s8MyModule16spiAvailableFuncyyF", -// CHECK-NEXT: "access": "public", -// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-NEXT: "access": "private", +// CHECK-NEXT: "file": "SOURCE_DIR/test/APIJSON/spi.swift", +// CHECK-NEXT: "linkage": "exported", +// CHECK-NEXT: "introduced": "10.10", +// CHECK-NEXT: "SPIAvailable": true +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "name": "_$s8MyModule8SPIClassC18noAvailabilityAttryyFTj", +// CHECK-NEXT: "access": "private", +// CHECK-NEXT: "file": "SOURCE_DIR/test/APIJSON/spi.swift", +// CHECK-NEXT: "linkage": "exported", +// CHECK-NEXT: "introduced": "11", +// CHECK-NEXT: "SPIAvailable": true +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "name": "_$s8MyModule8SPIClassC18noAvailabilityAttryyFTq", +// CHECK-NEXT: "access": "private", +// CHECK-NEXT: "file": "SOURCE_DIR/test/APIJSON/spi.swift", +// CHECK-NEXT: "linkage": "exported", +// CHECK-NEXT: "introduced": "11", +// CHECK-NEXT: "SPIAvailable": true +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "name": "_$s8MyModule8SPIClassCMa", +// CHECK-NEXT: "access": "private", +// CHECK-NEXT: "file": "SOURCE_DIR/test/APIJSON/spi.swift", +// CHECK-NEXT: "linkage": "exported", +// CHECK-NEXT: "introduced": "11", +// CHECK-NEXT: "SPIAvailable": true +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "name": "_$s8MyModule8SPIClassCMm", +// CHECK-NEXT: "access": "private", +// CHECK-NEXT: "file": "SOURCE_DIR/test/APIJSON/spi.swift", +// CHECK-NEXT: "linkage": "exported", +// CHECK-NEXT: "introduced": "11", +// CHECK-NEXT: "SPIAvailable": true +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "name": "_$s8MyModule8SPIClassCMn", +// CHECK-NEXT: "access": "private", +// CHECK-NEXT: "file": "SOURCE_DIR/test/APIJSON/spi.swift", +// CHECK-NEXT: "linkage": "exported", +// CHECK-NEXT: "introduced": "11", +// CHECK-NEXT: "SPIAvailable": true +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "name": "_$s8MyModule8SPIClassCMo", +// CHECK-NEXT: "access": "private", +// CHECK-NEXT: "file": "SOURCE_DIR/test/APIJSON/spi.swift", +// CHECK-NEXT: "linkage": "exported", +// CHECK-NEXT: "introduced": "11", +// CHECK-NEXT: "SPIAvailable": true +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "name": "_$s8MyModule8SPIClassCMu", +// CHECK-NEXT: "access": "private", +// CHECK-NEXT: "file": "SOURCE_DIR/test/APIJSON/spi.swift", +// CHECK-NEXT: "linkage": "exported", +// CHECK-NEXT: "introduced": "11", +// CHECK-NEXT: "SPIAvailable": true +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "name": "_$s8MyModule8SPIClassCN", +// CHECK-NEXT: "access": "private", +// CHECK-NEXT: "file": "SOURCE_DIR/test/APIJSON/spi.swift", // CHECK-NEXT: "linkage": "exported", -// CHECK-NEXT: "unavailable": true +// CHECK-NEXT: "introduced": "11", +// CHECK-NEXT: "SPIAvailable": true +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "name": "_$s8MyModule8SPIClassCfD", +// CHECK-NEXT: "access": "private", +// CHECK-NEXT: "file": "SOURCE_DIR/test/APIJSON/spi.swift", +// CHECK-NEXT: "linkage": "exported", +// CHECK-NEXT: "introduced": "11", +// CHECK-NEXT: "SPIAvailable": true +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "name": "_$s8MyModule8SPIClassCfd", +// CHECK-NEXT: "access": "private", +// CHECK-NEXT: "file": "SOURCE_DIR/test/APIJSON/spi.swift", +// CHECK-NEXT: "linkage": "exported", +// CHECK-NEXT: "introduced": "11", +// CHECK-NEXT: "SPIAvailable": true // CHECK-NEXT: } // CHECK-NEXT: ], // CHECK-NEXT: "interfaces": [ // CHECK-NEXT: { +// CHECK-NEXT: "name": "_TtC8MyModule7MyClass", +// CHECK-NEXT: "access": "private", +// CHECK-NEXT: "file": "SOURCE_DIR/test/APIJSON/spi.swift", +// CHECK-NEXT: "linkage": "exported", +// CHECK-NEXT: "super": "NSObject", +// CHECK-NEXT: "instanceMethods": [ +// CHECK-NEXT: { +// CHECK-NEXT: "name": "spiMethod", +// CHECK-NEXT: "access": "private", +// CHECK-NEXT: "file": "SOURCE_DIR/test/APIJSON/spi.swift" +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "name": "init", +// CHECK-NEXT: "access": "private", +// CHECK-NEXT: "file": "SOURCE_DIR/test/APIJSON/spi.swift" +// CHECK-NEXT: } +// CHECK-NEXT: ], +// CHECK-NEXT: "classMethods": [] +// CHECK-NEXT: }, +// CHECK-NEXT: { // CHECK-NEXT: "name": "_TtC8MyModule8MyClass2", // CHECK-NEXT: "access": "public", -// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface", +// CHECK-NEXT: "file": "SOURCE_DIR/test/APIJSON/spi.swift", // CHECK-NEXT: "linkage": "exported", // CHECK-NEXT: "super": "NSObject", // CHECK-NEXT: "instanceMethods": [ // CHECK-NEXT: { +// CHECK-NEXT: "name": "spiMethod", +// CHECK-NEXT: "access": "private", +// CHECK-NEXT: "file": "SOURCE_DIR/test/APIJSON/spi.swift" +// CHECK-NEXT: }, +// CHECK-NEXT: { // CHECK-NEXT: "name": "spiAvailableMethod", -// CHECK-NEXT: "access": "public", -// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface", -// CHECK-NEXT: "unavailable": true +// CHECK-NEXT: "access": "private", +// CHECK-NEXT: "file": "SOURCE_DIR/test/APIJSON/spi.swift", +// CHECK-NEXT: "introduced": "10.10", +// CHECK-NEXT: "SPIAvailable": true // CHECK-NEXT: }, // CHECK-NEXT: { // CHECK-NEXT: "name": "init", // CHECK-NEXT: "access": "public", -// CHECK-NEXT: "file": "/@input/MyModule.swiftinterface" +// CHECK-NEXT: "file": "SOURCE_DIR/test/APIJSON/spi.swift" // CHECK-NEXT: } // CHECK-NEXT: ], // CHECK-NEXT: "classMethods": [] // CHECK-NEXT: } // CHECK-NEXT: ], -// CHECK-NEXT: "categories": [], + // CHECK-NEXT: "categories": [], // CHECK-NEXT: "version": "1.0" // CHECK-NEXT: } - -// CHECK-SPI: { -// CHECK-SPI-NEXT: "target": -// CHECK-SPI-NEXT: "globals": [ -// CHECK-SPI-NEXT: { -// CHECK-SPI-NEXT: "name": "_$s8MyModule0A5ClassC9spiMethodyyFTj", -// CHECK-SPI-NEXT: "access": "private", -// CHECK-SPI-EXTRACT-NEXT: "file": "/@input/MyModule.swiftmodule", -// CHECK-SPI-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/spi.swift", -// CHECK-SPI-NEXT: "linkage": "exported" -// CHECK-SPI-NEXT: }, -// CHECK-SPI-NEXT: { -// CHECK-SPI-NEXT: "name": "_$s8MyModule0A5ClassC9spiMethodyyFTq", -// CHECK-SPI-NEXT: "access": "private", -// CHECK-SPI-EXTRACT-NEXT: "file": "/@input/MyModule.swiftmodule", -// CHECK-SPI-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/spi.swift", -// CHECK-SPI-NEXT: "linkage": "exported" -// CHECK-SPI-NEXT: }, -// CHECK-SPI-NEXT: { -// CHECK-SPI-NEXT: "name": "_$s8MyModule0A5ClassCACycfC", -// CHECK-SPI-NEXT: "access": "private", -// CHECK-SPI-EXTRACT-NEXT: "file": "/@input/MyModule.swiftmodule", -// CHECK-SPI-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/spi.swift", -// CHECK-SPI-NEXT: "linkage": "exported" -// CHECK-SPI-NEXT: }, -// CHECK-SPI-NEXT: { -// CHECK-SPI-NEXT: "name": "_$s8MyModule0A5ClassCACycfc", -// CHECK-SPI-NEXT: "access": "private", -// CHECK-SPI-EXTRACT-NEXT: "file": "/@input/MyModule.swiftmodule", -// CHECK-SPI-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/spi.swift", -// CHECK-SPI-NEXT: "linkage": "exported" -// CHECK-SPI-NEXT: }, -// CHECK-SPI-NEXT: { -// CHECK-SPI-NEXT: "name": "_$s8MyModule0A5ClassCMa", -// CHECK-SPI-NEXT: "access": "private", -// CHECK-SPI-EXTRACT-NEXT: "file": "/@input/MyModule.swiftmodule", -// CHECK-SPI-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/spi.swift", -// CHECK-SPI-NEXT: "linkage": "exported" -// CHECK-SPI-NEXT: }, -// CHECK-SPI-NEXT: { -// CHECK-SPI-NEXT: "name": "_$s8MyModule0A5ClassCMn", -// CHECK-SPI-NEXT: "access": "private", -// CHECK-SPI-EXTRACT-NEXT: "file": "/@input/MyModule.swiftmodule", -// CHECK-SPI-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/spi.swift", -// CHECK-SPI-NEXT: "linkage": "exported" -// CHECK-SPI-NEXT: }, -// CHECK-SPI-NEXT: { -// CHECK-SPI-NEXT: "name": "_$s8MyModule0A5ClassCMo", -// CHECK-SPI-NEXT: "access": "private", -// CHECK-SPI-EXTRACT-NEXT: "file": "/@input/MyModule.swiftmodule", -// CHECK-SPI-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/spi.swift", -// CHECK-SPI-NEXT: "linkage": "exported" -// CHECK-SPI-NEXT: }, -// CHECK-SPI-NEXT: { -// CHECK-SPI-NEXT: "name": "_$s8MyModule0A5ClassCMu", -// CHECK-SPI-NEXT: "access": "private", -// CHECK-SPI-EXTRACT-NEXT: "file": "/@input/MyModule.swiftmodule", -// CHECK-SPI-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/spi.swift", -// CHECK-SPI-NEXT: "linkage": "exported" -// CHECK-SPI-NEXT: }, -// CHECK-SPI-NEXT: { -// CHECK-SPI-NEXT: "name": "_$s8MyModule0A5ClassCN", -// CHECK-SPI-NEXT: "access": "private", -// CHECK-SPI-EXTRACT-NEXT: "file": "/@input/MyModule.swiftmodule", -// CHECK-SPI-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/spi.swift", -// CHECK-SPI-NEXT: "linkage": "exported" -// CHECK-SPI-NEXT: }, -// CHECK-SPI-NEXT: { -// CHECK-SPI-NEXT: "name": "_$s8MyModule0A5ClassCfD", -// CHECK-SPI-NEXT: "access": "private", -// CHECK-SPI-EXTRACT-NEXT: "file": "/@input/MyModule.swiftmodule", -// CHECK-SPI-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/spi.swift", -// CHECK-SPI-NEXT: "linkage": "exported" -// CHECK-SPI-NEXT: }, -// CHECK-SPI-NEXT: { -// CHECK-SPI-NEXT: "name": "_$s8MyModule0A6Class2C18spiAvailableMethodyyFTj", -// CHECK-SPI-NEXT: "access": "private", -// CHECK-SPI-EXTRACT-NEXT: "file": "/@input/MyModule.swiftmodule", -// CHECK-SPI-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/spi.swift", -// CHECK-SPI-NEXT: "linkage": "exported", -// CHECK-SPI-NEXT: "introduced": "10.10" -// CHECK-SPI-NEXT: }, -// CHECK-SPI-NEXT: { -// CHECK-SPI-NEXT: "name": "_$s8MyModule0A6Class2C18spiAvailableMethodyyFTq", -// CHECK-SPI-NEXT: "access": "private", -// CHECK-SPI-EXTRACT-NEXT: "file": "/@input/MyModule.swiftmodule", -// CHECK-SPI-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/spi.swift", -// CHECK-SPI-NEXT: "linkage": "exported", -// CHECK-SPI-NEXT: "introduced": "10.10" -// CHECK-SPI-NEXT: }, -// CHECK-SPI-NEXT: { -// CHECK-SPI-NEXT: "name": "_$s8MyModule0A6Class2C9spiMethodyyFTj", -// CHECK-SPI-NEXT: "access": "private", -// CHECK-SPI-EXTRACT-NEXT: "file": "/@input/MyModule.swiftmodule", -// CHECK-SPI-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/spi.swift", -// CHECK-SPI-NEXT: "linkage": "exported" -// CHECK-SPI-NEXT: }, -// CHECK-SPI-NEXT: { -// CHECK-SPI-NEXT: "name": "_$s8MyModule0A6Class2C9spiMethodyyFTq", -// CHECK-SPI-NEXT: "access": "private", -// CHECK-SPI-EXTRACT-NEXT: "file": "/@input/MyModule.swiftmodule", -// CHECK-SPI-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/spi.swift", -// CHECK-SPI-NEXT: "linkage": "exported" -// CHECK-SPI-NEXT: }, -// CHECK-SPI-NEXT: { -// CHECK-SPI-NEXT: "name": "_$s8MyModule0A6Class2CACycfC", -// CHECK-SPI-NEXT: "access": "public", -// CHECK-SPI-EXTRACT-NEXT: "file": "/@input/MyModule.swiftmodule", -// CHECK-SPI-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/spi.swift", -// CHECK-SPI-NEXT: "linkage": "exported" -// CHECK-SPI-NEXT: }, -// CHECK-SPI-NEXT: { -// CHECK-SPI-NEXT: "name": "_$s8MyModule0A6Class2CACycfc", -// CHECK-SPI-NEXT: "access": "public", -// CHECK-SPI-EXTRACT-NEXT: "file": "/@input/MyModule.swiftmodule", -// CHECK-SPI-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/spi.swift", -// CHECK-SPI-NEXT: "linkage": "exported" -// CHECK-SPI-NEXT: }, -// CHECK-SPI-NEXT: { -// CHECK-SPI-NEXT: "name": "_$s8MyModule0A6Class2CMa", -// CHECK-SPI-NEXT: "access": "public", -// CHECK-SPI-EXTRACT-NEXT: "file": "/@input/MyModule.swiftmodule", -// CHECK-SPI-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/spi.swift", -// CHECK-SPI-NEXT: "linkage": "exported" -// CHECK-SPI-NEXT: }, -// CHECK-SPI-NEXT: { -// CHECK-SPI-NEXT: "name": "_$s8MyModule0A6Class2CMn", -// CHECK-SPI-NEXT: "access": "public", -// CHECK-SPI-EXTRACT-NEXT: "file": "/@input/MyModule.swiftmodule", -// CHECK-SPI-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/spi.swift", -// CHECK-SPI-NEXT: "linkage": "exported" -// CHECK-SPI-NEXT: }, -// CHECK-SPI-NEXT: { -// CHECK-SPI-NEXT: "name": "_$s8MyModule0A6Class2CMo", -// CHECK-SPI-NEXT: "access": "public", -// CHECK-SPI-EXTRACT-NEXT: "file": "/@input/MyModule.swiftmodule", -// CHECK-SPI-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/spi.swift", -// CHECK-SPI-NEXT: "linkage": "exported" -// CHECK-SPI-NEXT: }, -// CHECK-SPI-NEXT: { -// CHECK-SPI-NEXT: "name": "_$s8MyModule0A6Class2CMu", -// CHECK-SPI-NEXT: "access": "public", -// CHECK-SPI-EXTRACT-NEXT: "file": "/@input/MyModule.swiftmodule", -// CHECK-SPI-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/spi.swift", -// CHECK-SPI-NEXT: "linkage": "exported" -// CHECK-SPI-NEXT: }, -// CHECK-SPI-NEXT: { -// CHECK-SPI-NEXT: "name": "_$s8MyModule0A6Class2CN", -// CHECK-SPI-NEXT: "access": "public", -// CHECK-SPI-EXTRACT-NEXT: "file": "/@input/MyModule.swiftmodule", -// CHECK-SPI-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/spi.swift", -// CHECK-SPI-NEXT: "linkage": "exported" -// CHECK-SPI-NEXT: }, -// CHECK-SPI-NEXT: { -// CHECK-SPI-NEXT: "name": "_$s8MyModule0A6Class2CfD", -// CHECK-SPI-NEXT: "access": "public", -// CHECK-SPI-EXTRACT-NEXT: "file": "/@input/MyModule.swiftmodule", -// CHECK-SPI-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/spi.swift", -// CHECK-SPI-NEXT: "linkage": "exported" -// CHECK-SPI-NEXT: }, -// CHECK-SPI-NEXT: { -// CHECK-SPI-NEXT: "name": "_$s8MyModule15newUnprovenFuncyyF", -// CHECK-SPI-NEXT: "access": "private", -// CHECK-SPI-EXTRACT-NEXT: "file": "/@input/MyModule.swiftmodule", -// CHECK-SPI-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/spi.swift", -// CHECK-SPI-NEXT: "linkage": "exported" -// CHECK-SPI-NEXT: }, -// CHECK-SPI-NEXT: { -// CHECK-SPI-NEXT: "name": "_$s8MyModule16spiAvailableFuncyyF", -// CHECK-SPI-NEXT: "access": "private", -// CHECK-SPI-EXTRACT-NEXT: "file": "/@input/MyModule.swiftmodule", -// CHECK-SPI-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/spi.swift", -// CHECK-SPI-NEXT: "linkage": "exported", -// CHECK-SPI-NEXT: "introduced": "10.10" -// CHECK-SPI-NEXT: } -// CHECK-SPI-NEXT: ], -// CHECK-SPI-NEXT: "interfaces": [ -// CHECK-SPI-NEXT: { -// CHECK-SPI-NEXT: "name": "_TtC8MyModule7MyClass", -// CHECK-SPI-NEXT: "access": "private", -// CHECK-SPI-EXTRACT-NEXT: "file": "/@input/MyModule.swiftmodule", -// CHECK-SPI-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/spi.swift", -// CHECK-SPI-NEXT: "linkage": "exported", -// CHECK-SPI-NEXT: "super": "NSObject", -// CHECK-SPI-NEXT: "instanceMethods": [ -// CHECK-SPI-NEXT: { -// CHECK-SPI-NEXT: "name": "spiMethod", -// CHECK-SPI-NEXT: "access": "private", -// CHECK-SPI-EXTRACT-NEXT: "file": "/@input/MyModule.swiftmodule" -// CHECK-SPI-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/spi.swift" -// CHECK-SPI-NEXT: }, -// CHECK-SPI-NEXT: { -// CHECK-SPI-NEXT: "name": "init", -// CHECK-SPI-NEXT: "access": "private", -// CHECK-SPI-EXTRACT-NEXT: "file": "/@input/MyModule.swiftmodule" -// CHECK-SPI-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/spi.swift" -// CHECK-SPI-NEXT: } -// CHECK-SPI-NEXT: ], -// CHECK-SPI-NEXT: "classMethods": [] -// CHECK-SPI-NEXT: }, -// CHECK-SPI-NEXT: { -// CHECK-SPI-NEXT: "name": "_TtC8MyModule8MyClass2", -// CHECK-SPI-NEXT: "access": "public", -// CHECK-SPI-EXTRACT-NEXT: "file": "/@input/MyModule.swiftmodule", -// CHECK-SPI-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/spi.swift", -// CHECK-SPI-NEXT: "linkage": "exported", -// CHECK-SPI-NEXT: "super": "NSObject", -// CHECK-SPI-NEXT: "instanceMethods": [ -// CHECK-SPI-NEXT: { -// CHECK-SPI-NEXT: "name": "spiMethod", -// CHECK-SPI-NEXT: "access": "private", -// CHECK-SPI-EXTRACT-NEXT: "file": "/@input/MyModule.swiftmodule" -// CHECK-SPI-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/spi.swift" -// CHECK-SPI-NEXT: }, -// CHECK-SPI-NEXT: { -// CHECK-SPI-NEXT: "name": "spiAvailableMethod", -// CHECK-SPI-NEXT: "access": "private", -// CHECK-SPI-EXTRACT-NEXT: "file": "/@input/MyModule.swiftmodule" -// CHECK-SPI-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/spi.swift", -// CHECK-SPI-NEXT: "introduced": "10.10" -// CHECK-SPI-NEXT: }, -// CHECK-SPI-NEXT: { -// CHECK-SPI-NEXT: "name": "init", -// CHECK-SPI-NEXT: "access": "public", -// CHECK-SPI-EXTRACT-NEXT: "file": "/@input/MyModule.swiftmodule" -// CHECK-SPI-EMIT-NEXT: "file": "SOURCE_DIR/test/APIJSON/spi.swift" -// CHECK-SPI-NEXT: } -// CHECK-SPI-NEXT: ], -// CHECK-SPI-NEXT: "classMethods": [] -// CHECK-SPI-NEXT: } -// CHECK-SPI-NEXT: ], - // CHECK-SPI-NEXT: "categories": [], -// CHECK-SPI-NEXT: "version": "1.0" -// CHECK-SPI-NEXT: } diff --git a/test/APIJSON/struct.swift b/test/APIJSON/struct.swift index 470ae19e9d8e4..6314059e36449 100644 --- a/test/APIJSON/struct.swift +++ b/test/APIJSON/struct.swift @@ -28,7 +28,8 @@ public struct TestStruct { // CHECK-NEXT: "name": "_$s8MyModule10TestStructVACycfC", // CHECK-NEXT: "access": "public", // CHECK-NEXT: "file": "SOURCE_DIR/test/APIJSON/struct.swift", -// CHECK-NEXT: "linkage": "exported" +// CHECK-NEXT: "linkage": "exported", +// CHECK-NEXT: "introduced": "10.13" // CHECK-NEXT: }, // CHECK-NEXT: { // CHECK-NEXT: "name": "_$s8MyModule10TestStructVMa",