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.
|
// Implementation-only imported, cannot be reexported.
|
||||||
return DisallowedOriginKind::ImplementationOnly;
|
return DisallowedOriginKind::ImplementationOnly;
|
||||||
} else if ((decl->isSPI() || decl->isAvailableAsSPI()) && !where.isSPI()) {
|
} else if ((decl->isSPI() || decl->isAvailableAsSPI()) && !where.isSPI()) {
|
||||||
// Allowing unavailable context to use @_spi_available decls.
|
if (decl->isAvailableAsSPI() && !decl->isSPI()) {
|
||||||
// Decls with @_spi_available aren't hidden entirely from public interfaces,
|
// Allowing unavailable context to use @_spi_available decls.
|
||||||
// thus public interfaces may still refer them. Be forgiving here so public
|
// Decls with @_spi_available aren't hidden entirely from public interfaces,
|
||||||
// interfaces can compile.
|
// thus public interfaces may still refer them. Be forgiving here so public
|
||||||
if (where.getUnavailablePlatformKind().hasValue() &&
|
// interfaces can compile.
|
||||||
decl->isAvailableAsSPI() && !decl->isSPI()) {
|
if (where.getUnavailablePlatformKind().hasValue())
|
||||||
return DisallowedOriginKind::None;
|
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.
|
// SPI can only be exported in SPI.
|
||||||
return where.getDeclContext()->getParentModule() == M ?
|
return where.getDeclContext()->getParentModule() == M ?
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
// REQUIRES: OS=macosx
|
// 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 api
|
||||||
// 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 api
|
||||||
|
|
||||||
#if NOT_UNDERLYING
|
#if NOT_UNDERLYING
|
||||||
import SPIContainer
|
import SPIContainer
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
// REQUIRES: OS=macosx
|
// 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
|
@_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
|
// 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
|
import SPIContainerImporter
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
// REQUIRES: OS=macosx
|
// REQUIRES: OS=macosx
|
||||||
// RUN: %empty-directory(%t/inputs)
|
// 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
|
#if Foo
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
// REQUIRES: VENDOR=apple
|
// REQUIRES: VENDOR=apple
|
||||||
// REQUIRES: OS=macosx
|
// 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, *)
|
@_spi_available(macOS 10.4, *)
|
||||||
public class MacOSSPIClass { public init() {} }
|
public class MacOSSPIClass { public init() {} }
|
||||||
|
|||||||
Reference in New Issue
Block a user