Files
swift-mirror/stdlib/public/SDK/ObjectiveC/ObjectiveC.swift
Jordan Rose cf8baedee2 Re-apply "Rename @transparent to @_transparent for now."
This re-applies 90fcbfe9a6. I'll be committing
the corresponding change to Foundation momentarily.
2015-11-16 10:53:56 -08:00

277 lines
7.5 KiB
Swift

//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
@_exported
import ObjectiveC
//===----------------------------------------------------------------------===//
// Objective-C Primitive Types
//===----------------------------------------------------------------------===//
/// The Objective-C BOOL type.
///
/// On 64-bit iOS, the Objective-C BOOL type is a typedef of C/C++
/// bool. Elsewhere, it is "signed char". The Clang importer imports it as
/// ObjCBool.
public struct ObjCBool : BooleanType, BooleanLiteralConvertible {
#if os(OSX) || (os(iOS) && (arch(i386) || arch(arm)))
// On OS X and 32-bit iOS, Objective-C's BOOL type is a "signed char".
var _value: Int8
init(_ value: Int8) {
self._value = value
}
public init(_ value: Bool) {
self._value = value ? 1 : 0
}
#else
// Everywhere else it is C/C++'s "Bool"
var _value : Bool
public init(_ value: Bool) {
self._value = value
}
#endif
/// The value of `self`, expressed as a `Bool`.
public var boolValue: Bool {
#if os(OSX) || (os(iOS) && (arch(i386) || arch(arm)))
return _value != 0
#else
return _value
#endif
}
/// Create an instance initialized to `value`.
@_transparent
public init(booleanLiteral value: Bool) {
self.init(value)
}
}
extension ObjCBool : _Reflectable {
/// Returns a mirror that reflects `self`.
public func _getMirror() -> _MirrorType {
return _reflect(boolValue)
}
}
extension ObjCBool : CustomStringConvertible {
/// A textual representation of `self`.
public var description: String {
return self.boolValue.description
}
}
// Functions used to implicitly bridge ObjCBool types to Swift's Bool type.
@warn_unused_result
public // COMPILER_INTRINSIC
func _convertBoolToObjCBool(x: Bool) -> ObjCBool {
return ObjCBool(x)
}
@warn_unused_result
public // COMPILER_INTRINSIC
func _convertObjCBoolToBool(x: ObjCBool) -> Bool {
return Bool(x)
}
/// The Objective-C SEL type.
///
/// The Objective-C SEL type is typically an opaque pointer. Swift
/// treats it as a distinct struct type, with operations to
/// convert between C strings and selectors.
///
/// The compiler has special knowledge of this type.
public struct Selector : StringLiteralConvertible, NilLiteralConvertible {
var ptr : COpaquePointer
/// Create a selector from a string.
public init(_ str : String) {
ptr = str.withCString { sel_registerName($0).ptr }
}
/// Create an instance initialized to `value`.
public init(unicodeScalarLiteral value: String) {
self.init(value)
}
/// Construct a selector from `value`.
public init(extendedGraphemeClusterLiteral value: String) {
self.init(value)
}
// FIXME: Fast-path this in the compiler, so we don't end up with
// the sel_registerName call at compile time.
/// Create an instance initialized to `value`.
public init(stringLiteral value: String) {
self = sel_registerName(value)
}
public init() {
ptr = nil
}
/// Create an instance initialized with `nil`.
@_transparent public
init(nilLiteral: ()) {
ptr = nil
}
}
@warn_unused_result
public func ==(lhs: Selector, rhs: Selector) -> Bool {
return sel_isEqual(lhs, rhs)
}
extension Selector : Equatable, Hashable {
/// The hash value.
///
/// **Axiom:** `x == y` implies `x.hashValue == y.hashValue`
///
/// - Note: the hash value is not guaranteed to be stable across
/// different invocations of the same program. Do not persist the
/// hash value across program runs.
public var hashValue: Int {
return ptr.hashValue
}
}
extension Selector : CustomStringConvertible {
/// A textual representation of `self`.
public var description: String {
if let s = String.fromCStringRepairingIllFormedUTF8(sel_getName(self)).0 {
return s
}
return "<NULL>"
}
}
extension String {
/// Construct the C string representation of an Objective-C selector.
public init(_sel: Selector) {
// FIXME: This misses the ASCII optimization.
self = String.fromCString(sel_getName(_sel))!
}
}
extension Selector : _Reflectable {
/// Returns a mirror that reflects `self`.
public func _getMirror() -> _MirrorType {
return _reflect(String(_sel: self))
}
}
//===----------------------------------------------------------------------===//
// NSZone
//===----------------------------------------------------------------------===//
public struct NSZone : NilLiteralConvertible {
var pointer : COpaquePointer
public init() { pointer = nil }
/// Create an instance initialized with `nil`.
@_transparent public
init(nilLiteral: ()) {
pointer = nil
}
}
//===----------------------------------------------------------------------===//
// FIXME: @autoreleasepool substitute
//===----------------------------------------------------------------------===//
@warn_unused_result
@asmname("objc_autoreleasePoolPush")
func __pushAutoreleasePool() -> COpaquePointer
@asmname("objc_autoreleasePoolPop")
func __popAutoreleasePool(pool: COpaquePointer)
public func autoreleasepool(@noescape code: () -> Void) {
let pool = __pushAutoreleasePool()
code()
__popAutoreleasePool(pool)
}
//===----------------------------------------------------------------------===//
// Mark YES and NO unavailable.
//===----------------------------------------------------------------------===//
@available(*, unavailable, message="Use 'Bool' value 'true' instead")
public var YES: ObjCBool {
fatalError("can't retrieve unavailable property")
}
@available(*, unavailable, message="Use 'Bool' value 'false' instead")
public var NO: ObjCBool {
fatalError("can't retrieve unavailable property")
}
// FIXME: We can't make the fully-generic versions @_transparent due to
// rdar://problem/19418937, so here are some @_transparent overloads
// for ObjCBool
@_transparent
@warn_unused_result
public func && <T : BooleanType>(
lhs: T, @autoclosure rhs: () -> ObjCBool
) -> Bool {
return lhs.boolValue ? rhs().boolValue : false
}
@_transparent
@warn_unused_result
public func || <T : BooleanType>(
lhs: T, @autoclosure rhs: () -> ObjCBool
) -> Bool {
return lhs.boolValue ? true : rhs().boolValue
}
//===----------------------------------------------------------------------===//
// NSObject
//===----------------------------------------------------------------------===//
// NSObject implements Equatable's == as -[NSObject isEqual:]
// NSObject implements Hashable's hashValue() as -[NSObject hash]
// FIXME: what about NSObjectProtocol?
extension NSObject : Equatable, Hashable {
/// The hash value.
///
/// **Axiom:** `x == y` implies `x.hashValue == y.hashValue`
///
/// - Note: the hash value is not guaranteed to be stable across
/// different invocations of the same program. Do not persist the
/// hash value across program runs.
public var hashValue: Int {
return hash
}
}
@warn_unused_result
public func == (lhs: NSObject, rhs: NSObject) -> Bool {
return lhs.isEqual(rhs)
}
extension NSObject : CVarArgType {
/// Transform `self` into a series of machine words that can be
/// appropriately interpreted by C varargs
public var _cVarArgEncoding: [Int] {
_autorelease(self)
return _encodeBitsAsWords(self)
}
}