mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Availability: only diagnose exposing SPI_AVAILABLE symbols in modules with library-level=API
For executable targets or private libraries, using SPI_AVAILABLE symbols should be allowed. rdar://91088241
This commit is contained in:
@@ -1546,13 +1546,21 @@ swift::getDisallowedOriginKind(const Decl *decl,
|
||||
// Implementation-only imported, cannot be reexported.
|
||||
return DisallowedOriginKind::ImplementationOnly;
|
||||
} else if ((decl->isSPI() || decl->isAvailableAsSPI()) && !where.isSPI()) {
|
||||
if (decl->isAvailableAsSPI() && !decl->isSPI()) {
|
||||
// Allowing unavailable context to use @_spi_available decls.
|
||||
// Decls with @_spi_available aren't hidden entirely from public interfaces,
|
||||
// thus public interfaces may still refer them. Be forgiving here so public
|
||||
// interfaces can compile.
|
||||
if (where.getUnavailablePlatformKind().hasValue() &&
|
||||
decl->isAvailableAsSPI() && !decl->isSPI()) {
|
||||
if (where.getUnavailablePlatformKind().hasValue())
|
||||
return DisallowedOriginKind::None;
|
||||
// We should only diagnose SPI_AVAILABLE usage when the library level is API.
|
||||
// Using SPI_AVAILABLE symbols in private frameworks or executable targets
|
||||
// should be allowed.
|
||||
if (auto *mod = where.getDeclContext()->getParentModule()) {
|
||||
if (mod->getLibraryLevel() != LibraryLevel::API) {
|
||||
return DisallowedOriginKind::None;
|
||||
}
|
||||
}
|
||||
}
|
||||
// SPI can only be exported in SPI.
|
||||
return where.getDeclContext()->getParentModule() == M ?
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// REQUIRES: OS=macosx
|
||||
// RUN: %target-swift-frontend -typecheck %s -F %S/Inputs/frameworks -verify -DNOT_UNDERLYING
|
||||
// RUN: %target-swift-frontend -typecheck %s -F %S/Inputs/frameworks -module-name SPIContainer -import-underlying-module -verify
|
||||
// RUN: %target-swift-frontend -typecheck %s -F %S/Inputs/frameworks -verify -DNOT_UNDERLYING -library-level api
|
||||
// RUN: %target-swift-frontend -typecheck %s -F %S/Inputs/frameworks -module-name SPIContainer -import-underlying-module -verify -library-level api
|
||||
|
||||
#if NOT_UNDERLYING
|
||||
import SPIContainer
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// REQUIRES: OS=macosx
|
||||
// RUN: %target-swift-frontend -typecheck %s -import-objc-header %S/Inputs/frameworks/SPIContainer.framework/Headers/SPIContainer.h -verify
|
||||
// RUN: %target-swift-frontend -typecheck %s -import-objc-header %S/Inputs/frameworks/SPIContainer.framework/Headers/SPIContainer.h -verify -library-level api
|
||||
|
||||
|
||||
@_spi(a) public let a: SPIInterface1
|
||||
|
||||
35
test/ClangImporter/availability_spi_library_level_spi.swift
Normal file
35
test/ClangImporter/availability_spi_library_level_spi.swift
Normal file
@@ -0,0 +1,35 @@
|
||||
// REQUIRES: OS=macosx
|
||||
|
||||
// RUN: %target-swift-frontend -typecheck %s -F %S/Inputs/frameworks -verify -DNOT_UNDERLYING
|
||||
// RUN: %target-swift-frontend -typecheck %s -F %S/Inputs/frameworks -verify -DNOT_UNDERLYING -library-level spi
|
||||
|
||||
// RUN: %target-swift-frontend -typecheck %s -F %S/Inputs/frameworks -module-name SPIContainer -import-underlying-module -verify
|
||||
// RUN: %target-swift-frontend -typecheck %s -F %S/Inputs/frameworks -module-name SPIContainer -import-underlying-module -verify -library-level spi
|
||||
|
||||
|
||||
#if NOT_UNDERLYING
|
||||
import SPIContainer
|
||||
#endif
|
||||
|
||||
@_spi(a) public let a: SPIInterface1
|
||||
@_spi(a) public let b: SPIInterface2
|
||||
|
||||
public let c: SPIInterface1
|
||||
public let d: SPIInterface2
|
||||
|
||||
@inlinable
|
||||
public func inlinableUsingSPI() {
|
||||
SharedInterface.foo()
|
||||
}
|
||||
|
||||
@available(macOS, unavailable)
|
||||
public let e: SPIInterface2
|
||||
|
||||
@available(iOS, unavailable)
|
||||
public let f: SPIInterface2
|
||||
|
||||
@inlinable
|
||||
@available(macOS, unavailable)
|
||||
public func inlinableUnavailableUsingSPI() {
|
||||
SharedInterface.foo()
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
// REQUIRES: OS=macosx
|
||||
// RUN: %target-swift-frontend -typecheck %s -F %S/Inputs/frameworks -verify
|
||||
// RUN: %target-swift-frontend -typecheck %s -F %S/Inputs/frameworks -verify -library-level api
|
||||
|
||||
import SPIContainerImporter
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
// REQUIRES: OS=macosx
|
||||
// RUN: %empty-directory(%t/inputs)
|
||||
// RUN: %target-swift-frontend -typecheck %s -F %S/../ClangImporter/Inputs/frameworks -DFoo -emit-module-interface-path %t/inputs/Foo.swiftinterface -module-name Foo -enable-library-evolution -disable-clang-spi
|
||||
// RUN: %target-swift-frontend -typecheck %s -F %S/../ClangImporter/Inputs/frameworks -DFoo -emit-module-interface-path %t/inputs/Foo.swiftinterface -module-name Foo -enable-library-evolution -disable-clang-spi -library-level api
|
||||
|
||||
// RUN: %target-swift-frontend -typecheck %s -F %S/../ClangImporter/Inputs/frameworks -enable-library-evolution -I %t/inputs -disable-clang-spi
|
||||
// RUN: %target-swift-frontend -typecheck %s -F %S/../ClangImporter/Inputs/frameworks -enable-library-evolution -I %t/inputs -disable-clang-spi -library-level api
|
||||
|
||||
// RUN: %target-swift-frontend -typecheck-module-from-interface %t/inputs/Foo.swiftinterface -F %S/../ClangImporter/Inputs/frameworks -disable-clang-spi
|
||||
// RUN: %target-swift-frontend -typecheck-module-from-interface %t/inputs/Foo.swiftinterface -F %S/../ClangImporter/Inputs/frameworks -disable-clang-spi -library-level api
|
||||
|
||||
|
||||
#if Foo
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// REQUIRES: VENDOR=apple
|
||||
// REQUIRES: OS=macosx
|
||||
// RUN: %target-typecheck-verify-swift -target %target-cpu-apple-macosx11.9
|
||||
// RUN: %target-typecheck-verify-swift -target %target-cpu-apple-macosx11.9 -library-level api
|
||||
|
||||
@_spi_available(macOS 10.4, *)
|
||||
public class MacOSSPIClass { public init() {} }
|
||||
|
||||
Reference in New Issue
Block a user