mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Use these queries to replace some duplicated code. Also, move the `attr_inlinable_available.swift` test to the `Availability` sub-directory since the test has more to do with availability checking than it has to do specifically with the `@inlinable` attr.
478 lines
15 KiB
Swift
478 lines
15 KiB
Swift
// RUN: %target-swift-frontend -typecheck -dump-availability-scopes %s -target %target-cpu-apple-macos50 -swift-version 5 > %t.dump 2>&1
|
|
// RUN: %FileCheck --strict-whitespace %s < %t.dump
|
|
|
|
// REQUIRES: OS=macosx
|
|
|
|
// CHECK: {{^}}(root version=50
|
|
|
|
// CHECK-NEXT: {{^}} (decl version=51 decl=SomeClass
|
|
// CHECK-NEXT: {{^}} (decl version=52 decl=someMethod()
|
|
// CHECK-NEXT: {{^}} (decl version=53 decl=someInnerFunc()
|
|
// CHECK-NEXT: {{^}} (decl version=53 decl=InnerClass
|
|
// CHECK-NEXT: {{^}} (decl version=54 decl=innerClassMethod
|
|
// CHECK-NEXT: {{^}} (decl_implicit version=51 decl=someStaticProperty
|
|
// CHECK-NEXT: {{^}} (decl version=52 decl=someStaticProperty
|
|
// CHECK-NEXT: {{^}} (decl_implicit version=51 decl=someStaticPropertyInferredType
|
|
// CHECK-NEXT: {{^}} (decl version=52 decl=someStaticPropertyInferredType
|
|
// CHECK-NEXT: {{^}} (decl_implicit version=51 decl=multiPatternStaticPropertyA
|
|
// CHECK-NEXT: {{^}} (decl version=52 decl=multiPatternStaticPropertyA
|
|
// CHECK-NEXT: {{^}} (decl_implicit version=51 decl=someComputedProperty
|
|
// CHECK-NEXT: {{^}} (decl version=52 decl=someComputedProperty
|
|
// CHECK-NEXT: {{^}} (decl version=52 decl=someOtherMethod()
|
|
@available(OSX 51, *)
|
|
class SomeClass {
|
|
@available(OSX 52, *)
|
|
func someMethod() {
|
|
|
|
@available(OSX 53, *)
|
|
func someInnerFunc() { }
|
|
|
|
@available(OSX 53, *)
|
|
class InnerClass {
|
|
@available(OSX 54, *)
|
|
func innerClassMethod() { }
|
|
}
|
|
}
|
|
|
|
func someUnrefinedMethod() { }
|
|
|
|
@available(OSX 52, *)
|
|
static var someStaticProperty: Int = 7
|
|
|
|
@available(OSX 52, *)
|
|
static var someStaticPropertyInferredType = 7
|
|
|
|
@available(OSX 52, *)
|
|
static var multiPatternStaticPropertyA = 7,
|
|
multiPatternStaticPropertyB = 8
|
|
|
|
@available(OSX 52, *)
|
|
var someComputedProperty: Int {
|
|
get { }
|
|
set(v) { }
|
|
}
|
|
|
|
@available(OSX 52, *)
|
|
func someOtherMethod() { }
|
|
}
|
|
|
|
// CHECK-NEXT: {{^}} (decl version=51 decl=someFunction()
|
|
@available(OSX 51, *)
|
|
func someFunction() { }
|
|
|
|
// CHECK-NEXT: {{^}} (decl version=51 decl=SomeProtocol
|
|
// CHECK-NEXT: {{^}} (decl version=52 decl=protoMethod()
|
|
// CHECK-NEXT: {{^}} (decl_implicit version=51 decl=protoProperty
|
|
// CHECK-NEXT: {{^}} (decl version=52 decl=protoProperty
|
|
@available(OSX 51, *)
|
|
protocol SomeProtocol {
|
|
@available(OSX 52, *)
|
|
func protoMethod() -> Int
|
|
|
|
@available(OSX 52, *)
|
|
var protoProperty: Int { get }
|
|
}
|
|
|
|
// CHECK-NEXT: {{^}} (decl_implicit version=50 decl=extension.SomeClass
|
|
// CHECK-NEXT: {{^}} (decl version=51 decl=extension.SomeClass
|
|
// CHECK-NEXT: {{^}} (decl version=52 decl=someExtensionFunction()
|
|
@available(OSX 51, *)
|
|
extension SomeClass {
|
|
@available(OSX 52, *)
|
|
func someExtensionFunction() { }
|
|
}
|
|
|
|
// CHECK-NEXT: {{^}} (decl version=51 decl=functionWithStmtCondition
|
|
// CHECK-NEXT: {{^}} (condition_following_availability version=52
|
|
// CHECK-NEXT: {{^}} (condition_following_availability version=53
|
|
// CHECK-NEXT: {{^}} (if_then version=53
|
|
// CHECK-NEXT: {{^}} (condition_following_availability version=54
|
|
// CHECK-NEXT: {{^}} (if_then version=54
|
|
// CHECK-NEXT: {{^}} (condition_following_availability version=55
|
|
// CHECK-NEXT: {{^}} (decl version=55 decl=funcInGuardElse()
|
|
// CHECK-NEXT: {{^}} (guard_fallthrough version=55
|
|
// CHECK-NEXT: {{^}} (condition_following_availability version=56
|
|
// CHECK-NEXT: {{^}} (guard_fallthrough version=56
|
|
// CHECK-NEXT: {{^}} (decl version=57 decl=funcInInnerIfElse()
|
|
// CHECK-NEXT: {{^}} (decl version=53 decl=funcInOuterIfElse()
|
|
@available(OSX 51, *)
|
|
func functionWithStmtCondition() {
|
|
if #available(OSX 52, *),
|
|
let x = (nil as Int?),
|
|
#available(OSX 53, *) {
|
|
if #available(OSX 54, *) {
|
|
guard #available(OSX 55, *) else {
|
|
@available(OSX 55, *)
|
|
func funcInGuardElse() { }
|
|
}
|
|
guard #available(OSX 56, *) else { }
|
|
} else {
|
|
@available(OSX 57, *)
|
|
func funcInInnerIfElse() { }
|
|
}
|
|
} else {
|
|
@available(OSX 53, *)
|
|
func funcInOuterIfElse() { }
|
|
}
|
|
}
|
|
|
|
// CHECK-NEXT: {{^}} (decl version=51 decl=functionWithUnnecessaryStmtCondition
|
|
// CHECK-NEXT: {{^}} (condition_following_availability version=53
|
|
// CHECK-NEXT: {{^}} (if_then version=53
|
|
// CHECK-NEXT: {{^}} (condition_following_availability version=54
|
|
// CHECK-NEXT: {{^}} (if_then version=54
|
|
|
|
@available(OSX 51, *)
|
|
func functionWithUnnecessaryStmtCondition() {
|
|
// Shouldn't introduce availability scope for then branch when unnecessary
|
|
if #available(OSX 51, *) {
|
|
}
|
|
|
|
if #available(OSX 10.9, *) {
|
|
}
|
|
|
|
// Nested in conjunctive statement condition
|
|
if #available(OSX 53, *),
|
|
let x = (nil as Int?),
|
|
#available(OSX 52, *) {
|
|
}
|
|
|
|
if #available(OSX 54, *),
|
|
#available(OSX 54, *) {
|
|
}
|
|
|
|
// Wildcard is same as minimum deployment target
|
|
if #available(iOS 7.0, *) {
|
|
}
|
|
}
|
|
|
|
// CHECK-NEXT: {{^}} (decl version=51 decl=functionWithUnnecessaryStmtConditionsHavingElseBranch
|
|
// CHECK-NEXT: {{^}} (if_else version=none
|
|
// CHECK-NEXT: {{^}} (decl version=none decl=funcInInnerIfElse()
|
|
// CHECK-NEXT: {{^}} (if_else version=none
|
|
// CHECK-NEXT: {{^}} (guard_else version=none
|
|
// CHECK-NEXT: {{^}} (guard_else version=none
|
|
// CHECK-NEXT: {{^}} (if_else version=none
|
|
|
|
@available(OSX 51, *)
|
|
func functionWithUnnecessaryStmtConditionsHavingElseBranch(p: Int?) {
|
|
// Else branch context version is bottom when check is unnecessary
|
|
if #available(OSX 51, *) {
|
|
} else {
|
|
if #available(OSX 52, *) {
|
|
}
|
|
|
|
@available(OSX 52, *)
|
|
func funcInInnerIfElse() { }
|
|
|
|
if #available(iOS 7.0, *) {
|
|
} else {
|
|
}
|
|
}
|
|
|
|
if #available(iOS 7.0, *) {
|
|
} else {
|
|
}
|
|
|
|
guard #available(iOS 8.0, *) else { }
|
|
|
|
// Else branch will execute if p is nil, so it is not dead.
|
|
if #available(iOS 7.0, *),
|
|
let x = p {
|
|
} else {
|
|
}
|
|
|
|
if #available(iOS 7.0, *),
|
|
let x = p,
|
|
#available(iOS 7.0, *) {
|
|
} else {
|
|
}
|
|
|
|
// Else branch is dead
|
|
guard #available(iOS 7.0, *),
|
|
#available(iOS 8.0, *) else { }
|
|
|
|
if #available(OSX 51, *),
|
|
#available(OSX 51, *) {
|
|
} else {
|
|
}
|
|
|
|
}
|
|
|
|
// CHECK-NEXT: {{^}} (decl version=51 decl=functionWithWhile()
|
|
// CHECK-NEXT: {{^}} (condition_following_availability version=52
|
|
// CHECK-NEXT: {{^}} (while_body version=52
|
|
// CHECK-NEXT: {{^}} (decl version=54 decl=funcInWhileBody()
|
|
@available(OSX 51, *)
|
|
func functionWithWhile() {
|
|
while #available(OSX 52, *),
|
|
let x = (nil as Int?) {
|
|
@available(OSX 54, *)
|
|
func funcInWhileBody() { }
|
|
}
|
|
}
|
|
|
|
// CHECK-NEXT: {{^}} (decl version=51 decl=functionWithDefer()
|
|
// CHECK-NEXT: {{^}} (condition_following_availability version=52
|
|
// CHECK-NEXT: {{^}} (if_then version=52
|
|
@available(OSX 51, *)
|
|
func functionWithDefer() {
|
|
defer {
|
|
if #available(OSX 52, *) {}
|
|
}
|
|
}
|
|
|
|
// CHECK-NEXT: {{^}} (decl_implicit version=50 decl=extension.SomeClass
|
|
// CHECK-NEXT: {{^}} (decl version=51 decl=extension.SomeClass
|
|
// CHECK-NEXT: {{^}} (decl_implicit version=51 decl=someStaticPropertyWithClosureInit
|
|
// CHECK-NEXT: {{^}} (decl version=52 decl=someStaticPropertyWithClosureInit
|
|
// CHECK-NEXT: {{^}} (condition_following_availability version=54
|
|
// CHECK-NEXT: {{^}} (if_then version=54
|
|
// CHECK-NEXT: {{^}} (decl_implicit version=51 decl=someStaticPropertyWithClosureInitInferred
|
|
// CHECK-NEXT: {{^}} (decl version=52 decl=someStaticPropertyWithClosureInitInferred
|
|
// CHECK-NEXT: {{^}} (condition_following_availability version=54
|
|
// CHECK-NEXT: {{^}} (if_then version=54
|
|
@available(OSX 51, *)
|
|
extension SomeClass {
|
|
@available(OSX 52, *)
|
|
static var someStaticPropertyWithClosureInit: Int = {
|
|
if #available(OSX 54, *) {
|
|
return 54
|
|
}
|
|
return 53
|
|
}()
|
|
|
|
@available(OSX 52, *)
|
|
static var someStaticPropertyWithClosureInitInferred = {
|
|
if #available(OSX 54, *) {
|
|
return 54
|
|
}
|
|
return 53
|
|
}()
|
|
}
|
|
|
|
// CHECK-NEXT: {{^}} (decl_implicit version=50 decl=extension.SomeClass
|
|
// CHECK-NEXT: {{^}} (decl version=50 unavailable=macOS decl=extension.SomeClass
|
|
// CHECK-NEXT: {{^}} (decl version=50 unavailable=macOS decl=functionWithStmtConditionsInUnavailableExt()
|
|
// CHECK-NEXT: {{^}} (condition_following_availability version=52 unavailable=macOS
|
|
// CHECK-NEXT: {{^}} (condition_following_availability version=53 unavailable=macOS
|
|
// CHECK-NEXT: {{^}} (if_then version=53 unavailable=macOS
|
|
// CHECK-NEXT: {{^}} (condition_following_availability version=54 unavailable=macOS
|
|
// CHECK-NEXT: {{^}} (if_then version=54 unavailable=macOS
|
|
// CHECK-NEXT: {{^}} (condition_following_availability version=55 unavailable=macOS
|
|
// CHECK-NEXT: {{^}} (decl version=54 unavailable=macOS decl=funcInGuardElse()
|
|
// CHECK-NEXT: {{^}} (guard_fallthrough version=55 unavailable=macOS
|
|
// CHECK-NEXT: {{^}} (condition_following_availability version=56 unavailable=macOS
|
|
// CHECK-NEXT: {{^}} (guard_fallthrough version=56 unavailable=macOS
|
|
// CHECK-NEXT: {{^}} (decl version=53 unavailable=macOS decl=funcInInnerIfElse()
|
|
// CHECK-NEXT: {{^}} (decl version=50 unavailable=macOS decl=funcInOuterIfElse()
|
|
@available(OSX, unavailable)
|
|
extension SomeClass {
|
|
@available(OSX 51, *)
|
|
func functionWithStmtConditionsInUnavailableExt() {
|
|
if #available(OSX 52, *),
|
|
let x = (nil as Int?),
|
|
#available(OSX 53, *) {
|
|
if #available(OSX 54, *) {
|
|
guard #available(OSX 55, *) else {
|
|
@available(OSX 55, *)
|
|
func funcInGuardElse() { }
|
|
}
|
|
guard #available(OSX 56, *) else { }
|
|
} else {
|
|
@available(OSX 57, *)
|
|
func funcInInnerIfElse() { }
|
|
}
|
|
} else {
|
|
@available(OSX 53, *)
|
|
func funcInOuterIfElse() { }
|
|
}
|
|
}
|
|
}
|
|
|
|
// CHECK-NEXT: {{^}} (decl_implicit version=50 decl=wrappedValue
|
|
|
|
@propertyWrapper
|
|
struct Wrapper<T> {
|
|
var wrappedValue: T
|
|
}
|
|
|
|
// CHECK-NEXT: {{^}} (decl version=51 decl=SomeStruct
|
|
// CHECK-NEXT: {{^}} (decl_implicit version=51 decl=someLazyVar
|
|
// CHECK-NEXT: {{^}} (condition_following_availability version=52
|
|
// CHECK-NEXT: {{^}} (guard_fallthrough version=52
|
|
// CHECK-NEXT: {{^}} (decl_implicit version=51 decl=someWrappedVar
|
|
// CHECK-NEXT: {{^}} (condition_following_availability version=52
|
|
// CHECK-NEXT: {{^}} (guard_fallthrough version=52
|
|
// CHECK-NEXT: {{^}} (decl version=52 decl=someMethodAvailable52()
|
|
@available(OSX 51, *)
|
|
struct SomeStruct {
|
|
lazy var someLazyVar = {
|
|
guard #available(OSX 52, *) else {
|
|
return someMethod()
|
|
}
|
|
return someMethodAvailable52()
|
|
}()
|
|
|
|
@Wrapper var someWrappedVar = {
|
|
guard #available(OSX 52, *) else {
|
|
return 51
|
|
}
|
|
return 52
|
|
}()
|
|
|
|
func someMethod() -> Int { return 51 }
|
|
|
|
@available(OSX 52, *)
|
|
func someMethodAvailable52() -> Int { return 52 }
|
|
}
|
|
|
|
// CHECK-NEXT: {{^}} (decl version=51 decl=SomeEnum
|
|
// CHECK-NEXT: {{^}} (decl version=52 decl=a
|
|
// CHECK-NEXT: {{^}} (decl version=53 decl=b
|
|
|
|
@available(OSX 51, *)
|
|
enum SomeEnum {
|
|
@available(OSX 52, *)
|
|
case a
|
|
|
|
@available(OSX 53, *)
|
|
case b, c
|
|
}
|
|
|
|
// CHECK-NEXT: {{^}} (decl_implicit version=50 decl=someComputedGlobalVar
|
|
// CHECK-NEXT: {{^}} (decl version=51 decl=_
|
|
// CHECK-NEXT: {{^}} (decl version=52 decl=_
|
|
|
|
var someComputedGlobalVar: Int {
|
|
@available(OSX 51, *)
|
|
get { 1 }
|
|
|
|
@available(OSX 52, *)
|
|
set { }
|
|
}
|
|
|
|
// CHECK-NEXT: {{^}} (decl_implicit version=50 decl=interpolated
|
|
// CHECK-NEXT: {{^}} (decl_implicit version=50 decl=string
|
|
|
|
func testStringInterpolation() {
|
|
let interpolated = """
|
|
\([""].map {
|
|
let string = $0
|
|
return string
|
|
})
|
|
"""
|
|
}
|
|
|
|
// CHECK-NEXT: {{^}} (decl_implicit version=50 decl=result
|
|
// CHECK-NEXT: {{^}} (decl_implicit version=50 decl=unusedA
|
|
// CHECK-NEXT: {{^}} (decl_implicit version=50 decl=unusedB
|
|
|
|
func testSequenceExprs(b: Bool, x: Int?) {
|
|
let result = b
|
|
? x.map {
|
|
let unusedA: Int
|
|
return $0
|
|
}
|
|
: x.map {
|
|
let unusedB: Int
|
|
return $0
|
|
}
|
|
}
|
|
|
|
// CHECK-NEXT: {{^}} (decl version=50 unavailable=macOS decl=unavailableOnMacOS()
|
|
// CHECK-NEXT: {{^}} (decl_implicit version=50 unavailable=macOS decl=x
|
|
|
|
@available(macOS, unavailable)
|
|
func unavailableOnMacOS() {
|
|
let x = 1
|
|
}
|
|
|
|
// CHECK-NEXT: {{^}} (decl_implicit version=50 decl=extension.SomeEnum
|
|
// CHECK-NEXT: {{^}} (decl version=51 decl=extension.SomeEnum
|
|
// CHECK-NEXT: {{^}} (decl_implicit version=51 decl=unavailableOnMacOS
|
|
// CHECK-NEXT: {{^}} (decl version=51 unavailable=macOS decl=unavailableOnMacOS
|
|
@available(OSX 51, *)
|
|
extension SomeEnum {
|
|
@available(macOS, unavailable)
|
|
var unavailableOnMacOS: Int { 1 }
|
|
}
|
|
|
|
// CHECK-NEXT: {{^}} (decl_implicit version=50 decl=extension.SomeEnum
|
|
// CHECK-NEXT: {{^}} (decl version=50 unavailable=macOS decl=extension.SomeEnum
|
|
// CHECK-NEXT: {{^}} (decl_implicit version=50 unavailable=macOS decl=availableMacOS_52
|
|
// CHECK-NEXT: {{^}} (decl version=50 unavailable=macOS decl=availableMacOS_52
|
|
// CHECK-NEXT: {{^}} (decl version=50 unavailable=* decl=neverAvailable()
|
|
|
|
@available(macOS, unavailable)
|
|
extension SomeEnum {
|
|
@available(OSX 52, *)
|
|
var availableMacOS_52: Int { 1 }
|
|
|
|
@available(macOSApplicationExtension, unavailable)
|
|
func unavailableInAppExtensions() {}
|
|
|
|
@available(*, unavailable)
|
|
func neverAvailable() {}
|
|
}
|
|
|
|
// CHECK-NEXT: {{^}} (decl version=50 unavailable=macOS decl=unavailableOnMacOSAndIntroduced()
|
|
|
|
@available(macOS, unavailable)
|
|
@available(macOS, introduced: 52)
|
|
func unavailableOnMacOSAndIntroduced() {
|
|
}
|
|
|
|
// CHECK-NEXT: {{^}} (decl version=50 unavailable=macOS decl=introducedOnMacOSAndUnavailable()
|
|
|
|
@available(macOS, introduced: 53)
|
|
@available(macOS, unavailable)
|
|
func introducedOnMacOSAndUnavailable() {
|
|
}
|
|
|
|
|
|
// CHECK-NEXT: {{^}} (decl version=50 unavailable=macOS decl=unavailableOnMacOSAndIntroducedSameAttr()
|
|
|
|
@available(macOS, unavailable, introduced: 54)
|
|
func unavailableOnMacOSAndIntroducedSameAttr() {
|
|
}
|
|
|
|
// CHECK-NEXT: {{^}} (decl version=50 unavailable=* decl=NeverAvailable
|
|
// CHECK-NEXT: {{^}} (decl version=50 unavailable=* decl=unavailableOnMacOS()
|
|
|
|
@available(*, unavailable)
|
|
struct NeverAvailable {
|
|
@available(macOS, unavailable)
|
|
func unavailableOnMacOS() {}
|
|
}
|
|
|
|
// CHECK-NEXT: {{^}} (decl version=50 deprecated decl=deprecatedOnMacOS()
|
|
// CHECK-NEXT: {{^}} (decl_implicit version=50 deprecated decl=x
|
|
|
|
@available(macOS, deprecated)
|
|
func deprecatedOnMacOS() {
|
|
let x = 1
|
|
}
|
|
|
|
// Since availableOniOS() doesn't have any active @available attributes it
|
|
// shouldn't create a scope.
|
|
// CHECK-NOT: availableOniOS
|
|
|
|
@available(iOS, introduced: 53)
|
|
func availableOniOS() { }
|
|
|
|
// CHECK-NEXT: {{^}} (decl version=50 decl=availableInSwift5
|
|
|
|
@available(swift 5)
|
|
func availableInSwift5() { }
|
|
|
|
// CHECK-NEXT: {{^}} (decl version=50 unavailable=swift decl=availableInSwift6
|
|
|
|
@available(swift 6)
|
|
func availableInSwift6() { }
|
|
|
|
// CHECK-NEXT: {{^}} (decl version=51 decl=FinalDecl
|
|
|
|
@available(OSX 51, *)
|
|
typealias FinalDecl = Int
|