Files
swift-mirror/stdlib/objc/ObjectiveC.swift
Dmitri Hrybenko f370ca0746 stdlib: fix a bunch of various Unicode issues, primarily in UTF-8 decoding
In UTF-8 decoder:
- implement U+FFFD insertion according to the recommendation given in the
  Unicode spec.  This required changing the decoder to become stateful, which
  significantly increased complexity due to the need to maintain an internal
  buffer.
- reject invalid code unit sequences properly instead of crashing rdar://16767868
- reject overlong sequences rdar://16767911

In stdlib:
- change APIs that assume that UTF decoding can never fail to account for
  possibility of errors
- fix a bug in UnicodeScalarView that could cause a crash during backward
  iteration if U+8000 is present in the string
- allow noncharacters in UnicodeScalar.  They are explicitly allowed in the
  definition of "Unicode scalar" in the specification.  Disallowing noncharacters
  in UnicodeScalar prevents actually using these scalar values as internal
  special values during string processing, which is exactly the reason why they
  are reserved in the first place.
- fix a crash in String.fromCString() that could happen if it was passed a null
  pointer

In Lexer:
- allow noncharacters in string literals.  These Unicode scalar values are not
  allowed to be exchanged externally, but it is totally reasonable to have them
  in literals as long as they don't escape the program.  For example, using
  U+FFFF as a delimiter and then calling str.split("\uffff") is completely
  reasonable.

This is a lot of changes in a single commit; the primary reason why they are
lumped together is the need to change stdlib APIs to account for the
possibility of UTF decoding failure, and this has long-reaching effects
throughout stdlib where these APIs are used.


Swift SVN r19045
2014-06-20 13:07:40 +00:00

127 lines
3.7 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
//===----------------------------------------------------------------------===//
// FIXME: Objective-C types belong in a layer below the Objective-C support
// libraries, not here.
extension ObjCBool : Printable {
var description: String {
return self.getLogicValue().description
}
}
/// 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.
struct Selector : StringLiteralConvertible, NilLiteralConvertible {
var ptr : COpaquePointer
/// Create a selector from a string.
init(_ str : String) {
ptr = str.withCString { sel_registerName($0).ptr }
}
/// Construct a selector from a string literal.
static func convertFromExtendedGraphemeClusterLiteral(
value: CString) -> Selector {
return convertFromStringLiteral(value)
}
/// Construct a selector from a string literal.
///
/// FIXME: Fast-path this in the compiler, so we don't end up with
/// the sel_registerName call at compile time.
static func convertFromStringLiteral(value: CString) -> Selector {
return sel_registerName(value)
}
init() {
ptr = nil
}
@transparent
static func convertFromNilLiteral() -> Selector {
return Selector()
}
}
func ==(lhs: Selector, rhs: Selector) -> Bool {
return sel_isEqual(lhs, rhs)
}
extension Selector : Equatable, Hashable {
var hashValue: Int {
return ptr.hashValue
}
}
extension Selector : Printable {
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.
init(_sel: Selector) {
// FIXME: This misses the ASCII optimization.
self = String.fromCString(sel_getName(_sel))!
}
}
// Functions used to implicitly bridge ObjCBool types to Swift's Bool type.
func _convertBoolToObjCBool(x: Bool) -> ObjCBool {
return x
}
func _convertObjCBoolToBool(x: ObjCBool) -> Bool {
return x
}
func ~=(x: NSObject, y: NSObject) -> Bool {
return x.isEqual(y)
}
//===----------------------------------------------------------------------===//
// FIXME: @autoreleasepool substitute
//===----------------------------------------------------------------------===//
@asmname("objc_autoreleasePoolPush") func __pushAutoreleasePool() -> COpaquePointer
@asmname("objc_autoreleasePoolPop") func __popAutoreleasePool(pool: COpaquePointer)
func autoreleasepool(code: () -> ()) {
var pool = __pushAutoreleasePool()
code()
__popAutoreleasePool(pool)
}
//===----------------------------------------------------------------------===//
// Mark YES and NO unavailable.
//===----------------------------------------------------------------------===//
@availability(*, unavailable, message="Use 'Bool' value 'true' instead") var YES : ObjCBool = Bool.true
@availability(*, unavailable, message="Use 'Bool' value 'false' instead") var NO : ObjCBool = Bool.false