| //===----------------------------------------------------------------------===// |
| // |
| // This source file is part of the Swift.org open source project |
| // |
| // Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors |
| // Licensed under Apache License v2.0 with Runtime Library Exception |
| // |
| // See https://swift.org/LICENSE.txt for license information |
| // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors |
| // |
| //===----------------------------------------------------------------------===// |
| // Swift Standard Prolog Library. |
| //===----------------------------------------------------------------------===// |
| |
| //===----------------------------------------------------------------------===// |
| // Standardized uninhabited type |
| //===----------------------------------------------------------------------===// |
| /// The return type of functions that do not return normally, that is, a type |
| /// with no values. |
| /// |
| /// Use `Never` as the return type when declaring a closure, function, or |
| /// method that unconditionally throws an error, traps, or otherwise does |
| /// not terminate. |
| /// |
| /// func crashAndBurn() -> Never { |
| /// fatalError("Something very, very bad happened") |
| /// } |
| @_frozen |
| public enum Never {} |
| |
| extension Never: Error {} |
| |
| extension Never: Equatable {} |
| |
| extension Never: Comparable { |
| public static func < (lhs: Never, rhs: Never) -> Bool { |
| } |
| } |
| |
| extension Never: Hashable {} |
| |
| //===----------------------------------------------------------------------===// |
| // Standardized aliases |
| //===----------------------------------------------------------------------===// |
| /// The return type of functions that don't explicitly specify a return type, |
| /// that is, an empty tuple `()`. |
| /// |
| /// When declaring a function or method, you don't need to specify a return |
| /// type if no value will be returned. However, the type of a function, |
| /// method, or closure always includes a return type, which is `Void` if |
| /// otherwise unspecified. |
| /// |
| /// Use `Void` or an empty tuple as the return type when declaring a closure, |
| /// function, or method that doesn't return a value. |
| /// |
| /// // No return type declared: |
| /// func logMessage(_ s: String) { |
| /// print("Message: \(s)") |
| /// } |
| /// |
| /// let logger: (String) -> Void = logMessage |
| /// logger("This is a void function") |
| /// // Prints "Message: This is a void function" |
| public typealias Void = () |
| |
| //===----------------------------------------------------------------------===// |
| // Aliases for floating point types |
| //===----------------------------------------------------------------------===// |
| // FIXME: it should be the other way round, Float = Float32, Double = Float64, |
| // but the type checker loses sugar currently, and ends up displaying 'FloatXX' |
| // in diagnostics. |
| /// A 32-bit floating point type. |
| public typealias Float32 = Float |
| /// A 64-bit floating point type. |
| public typealias Float64 = Double |
| |
| //===----------------------------------------------------------------------===// |
| // Default types for unconstrained literals |
| //===----------------------------------------------------------------------===// |
| /// The default type for an otherwise-unconstrained integer literal. |
| public typealias IntegerLiteralType = Int |
| /// The default type for an otherwise-unconstrained floating point literal. |
| public typealias FloatLiteralType = Double |
| |
| /// The default type for an otherwise-unconstrained Boolean literal. |
| /// |
| /// When you create a constant or variable using one of the Boolean literals |
| /// `true` or `false`, the resulting type is determined by the |
| /// `BooleanLiteralType` alias. For example: |
| /// |
| /// let isBool = true |
| /// print("isBool is a '\(type(of: isBool))'") |
| /// // Prints "isBool is a 'Bool'" |
| /// |
| /// The type aliased by `BooleanLiteralType` must conform to the |
| /// `ExpressibleByBooleanLiteral` protocol. |
| public typealias BooleanLiteralType = Bool |
| |
| /// The default type for an otherwise-unconstrained unicode scalar literal. |
| public typealias UnicodeScalarType = String |
| /// The default type for an otherwise-unconstrained Unicode extended |
| /// grapheme cluster literal. |
| public typealias ExtendedGraphemeClusterType = String |
| /// The default type for an otherwise-unconstrained string literal. |
| public typealias StringLiteralType = String |
| |
| //===----------------------------------------------------------------------===// |
| // Default types for unconstrained number literals |
| //===----------------------------------------------------------------------===// |
| #if !os(Windows) && (arch(i386) || arch(x86_64)) |
| public typealias _MaxBuiltinFloatType = Builtin.FPIEEE80 |
| #else |
| public typealias _MaxBuiltinFloatType = Builtin.FPIEEE64 |
| #endif |
| |
| //===----------------------------------------------------------------------===// |
| // Standard protocols |
| //===----------------------------------------------------------------------===// |
| |
| #if _runtime(_ObjC) |
| /// The protocol to which all classes implicitly conform. |
| /// |
| /// You use `AnyObject` when you need the flexibility of an untyped object or |
| /// when you use bridged Objective-C methods and properties that return an |
| /// untyped result. `AnyObject` can be used as the concrete type for an |
| /// instance of any class, class type, or class-only protocol. For example: |
| /// |
| /// class FloatRef { |
| /// let value: Float |
| /// init(_ value: Float) { |
| /// self.value = value |
| /// } |
| /// } |
| /// |
| /// let x = FloatRef(2.3) |
| /// let y: AnyObject = x |
| /// let z: AnyObject = FloatRef.self |
| /// |
| /// `AnyObject` can also be used as the concrete type for an instance of a type |
| /// that bridges to an Objective-C class. Many value types in Swift bridge to |
| /// Objective-C counterparts, like `String` and `Int`. |
| /// |
| /// let s: AnyObject = "This is a bridged string." as NSString |
| /// print(s is NSString) |
| /// // Prints "true" |
| /// |
| /// let v: AnyObject = 100 as NSNumber |
| /// print(type(of: v)) |
| /// // Prints "__NSCFNumber" |
| /// |
| /// The flexible behavior of the `AnyObject` protocol is similar to |
| /// Objective-C's `id` type. For this reason, imported Objective-C types |
| /// frequently use `AnyObject` as the type for properties, method parameters, |
| /// and return values. |
| /// |
| /// Casting AnyObject Instances to a Known Type |
| /// =========================================== |
| /// |
| /// Objects with a concrete type of `AnyObject` maintain a specific dynamic |
| /// type and can be cast to that type using one of the type-cast operators |
| /// (`as`, `as?`, or `as!`). |
| /// |
| /// This example uses the conditional downcast operator (`as?`) to |
| /// conditionally cast the `s` constant declared above to an instance of |
| /// Swift's `String` type. |
| /// |
| /// if let message = s as? String { |
| /// print("Successful cast to String: \(message)") |
| /// } |
| /// // Prints "Successful cast to String: This is a bridged string." |
| /// |
| /// If you have prior knowledge that an `AnyObject` instance has a particular |
| /// type, you can use the unconditional downcast operator (`as!`). Performing |
| /// an invalid cast triggers a runtime error. |
| /// |
| /// let message = s as! String |
| /// print("Successful cast to String: \(message)") |
| /// // Prints "Successful cast to String: This is a bridged string." |
| /// |
| /// let badCase = v as! String |
| /// // Runtime error |
| /// |
| /// Casting is always safe in the context of a `switch` statement. |
| /// |
| /// let mixedArray: [AnyObject] = [s, v] |
| /// for object in mixedArray { |
| /// switch object { |
| /// case let x as String: |
| /// print("'\(x)' is a String") |
| /// default: |
| /// print("'\(object)' is not a String") |
| /// } |
| /// } |
| /// // Prints "'This is a bridged string.' is a String" |
| /// // Prints "'100' is not a String" |
| /// |
| /// Accessing Objective-C Methods and Properties |
| /// ============================================ |
| /// |
| /// When you use `AnyObject` as a concrete type, you have at your disposal |
| /// every `@objc` method and property---that is, methods and properties |
| /// imported from Objective-C or marked with the `@objc` attribute. Because |
| /// Swift can't guarantee at compile time that these methods and properties |
| /// are actually available on an `AnyObject` instance's underlying type, these |
| /// `@objc` symbols are available as implicitly unwrapped optional methods and |
| /// properties, respectively. |
| /// |
| /// This example defines an `IntegerRef` type with an `@objc` method named |
| /// `getIntegerValue()`. |
| /// |
| /// class IntegerRef { |
| /// let value: Int |
| /// init(_ value: Int) { |
| /// self.value = value |
| /// } |
| /// |
| /// @objc func getIntegerValue() -> Int { |
| /// return value |
| /// } |
| /// } |
| /// |
| /// func getObject() -> AnyObject { |
| /// return IntegerRef(100) |
| /// } |
| /// |
| /// let obj: AnyObject = getObject() |
| /// |
| /// In the example, `obj` has a static type of `AnyObject` and a dynamic type |
| /// of `IntegerRef`. You can use optional chaining to call the `@objc` method |
| /// `getIntegerValue()` on `obj` safely. If you're sure of the dynamic type of |
| /// `obj`, you can call `getIntegerValue()` directly. |
| /// |
| /// let possibleValue = obj.getIntegerValue?() |
| /// print(possibleValue) |
| /// // Prints "Optional(100)" |
| /// |
| /// let certainValue = obj.getIntegerValue() |
| /// print(certainValue) |
| /// // Prints "100" |
| /// |
| /// If the dynamic type of `obj` doesn't implement a `getIntegerValue()` |
| /// method, the system returns a runtime error when you initialize |
| /// `certainValue`. |
| /// |
| /// Alternatively, if you need to test whether `obj.getIntegerValue()` exists, |
| /// use optional binding before calling the method. |
| /// |
| /// if let f = obj.getIntegerValue { |
| /// print("The value of 'obj' is \(f())") |
| /// } else { |
| /// print("'obj' does not have a 'getIntegerValue()' method") |
| /// } |
| /// // Prints "The value of 'obj' is 100" |
| public typealias AnyObject = Builtin.AnyObject |
| #else |
| /// The protocol to which all classes implicitly conform. |
| public typealias AnyObject = Builtin.AnyObject |
| #endif |
| |
| /// The protocol to which all class types implicitly conform. |
| /// |
| /// You can use the `AnyClass` protocol as the concrete type for an instance of |
| /// any class. When you do, all known `@objc` class methods and properties are |
| /// available as implicitly unwrapped optional methods and properties, |
| /// respectively. For example: |
| /// |
| /// class IntegerRef { |
| /// @objc class func getDefaultValue() -> Int { |
| /// return 42 |
| /// } |
| /// } |
| /// |
| /// func getDefaultValue(_ c: AnyClass) -> Int? { |
| /// return c.getDefaultValue?() |
| /// } |
| /// |
| /// The `getDefaultValue(_:)` function uses optional chaining to safely call |
| /// the implicitly unwrapped class method on `c`. Calling the function with |
| /// different class types shows how the `getDefaultValue()` class method is |
| /// only conditionally available. |
| /// |
| /// print(getDefaultValue(IntegerRef.self)) |
| /// // Prints "Optional(42)" |
| /// |
| /// print(getDefaultValue(NSString.self)) |
| /// // Prints "nil" |
| public typealias AnyClass = AnyObject.Type |
| |
| //===----------------------------------------------------------------------===// |
| // Standard pattern matching forms |
| //===----------------------------------------------------------------------===// |
| |
| /// Returns a Boolean value indicating whether two arguments match by value |
| /// equality. |
| /// |
| /// The pattern-matching operator (`~=`) is used internally in `case` |
| /// statements for pattern matching. When you match against an `Equatable` |
| /// value in a `case` statement, this operator is called behind the scenes. |
| /// |
| /// let weekday = 3 |
| /// let lunch: String |
| /// switch weekday { |
| /// case 3: |
| /// lunch = "Taco Tuesday!" |
| /// default: |
| /// lunch = "Pizza again." |
| /// } |
| /// // lunch == "Taco Tuesday!" |
| /// |
| /// In this example, the `case 3` expression uses this pattern-matching |
| /// operator to test whether `weekday` is equal to the value `3`. |
| /// |
| /// - Note: In most cases, you should use the equal-to operator (`==`) to test |
| /// whether two instances are equal. The pattern-matching operator is |
| /// primarily intended to enable `case` statement pattern matching. |
| /// |
| /// - Parameters: |
| /// - lhs: A value to compare. |
| /// - rhs: Another value to compare. |
| @_transparent |
| public func ~= <T : Equatable>(a: T, b: T) -> Bool { |
| return a == b |
| } |
| |
| //===----------------------------------------------------------------------===// |
| // Standard precedence groups |
| //===----------------------------------------------------------------------===// |
| |
| precedencegroup AssignmentPrecedence { |
| assignment: true |
| associativity: right |
| } |
| precedencegroup FunctionArrowPrecedence { |
| associativity: right |
| higherThan: AssignmentPrecedence |
| } |
| precedencegroup TernaryPrecedence { |
| associativity: right |
| higherThan: FunctionArrowPrecedence |
| } |
| precedencegroup DefaultPrecedence { |
| higherThan: TernaryPrecedence |
| } |
| precedencegroup LogicalDisjunctionPrecedence { |
| associativity: left |
| higherThan: TernaryPrecedence |
| } |
| precedencegroup LogicalConjunctionPrecedence { |
| associativity: left |
| higherThan: LogicalDisjunctionPrecedence |
| } |
| precedencegroup ComparisonPrecedence { |
| higherThan: LogicalConjunctionPrecedence |
| } |
| precedencegroup NilCoalescingPrecedence { |
| associativity: right |
| higherThan: ComparisonPrecedence |
| } |
| precedencegroup CastingPrecedence { |
| higherThan: NilCoalescingPrecedence |
| } |
| precedencegroup RangeFormationPrecedence { |
| higherThan: CastingPrecedence |
| } |
| precedencegroup AdditionPrecedence { |
| associativity: left |
| higherThan: RangeFormationPrecedence |
| } |
| precedencegroup MultiplicationPrecedence { |
| associativity: left |
| higherThan: AdditionPrecedence |
| } |
| precedencegroup BitwiseShiftPrecedence { |
| higherThan: MultiplicationPrecedence |
| } |
| |
| |
| //===----------------------------------------------------------------------===// |
| // Standard operators |
| //===----------------------------------------------------------------------===// |
| |
| // Standard postfix operators. |
| postfix operator ++ |
| postfix operator -- |
| postfix operator ... : Comparable |
| |
| // Optional<T> unwrapping operator is built into the compiler as a part of |
| // postfix expression grammar. |
| // |
| // postfix operator ! |
| |
| // Standard prefix operators. |
| prefix operator ++ |
| prefix operator -- |
| prefix operator ! : Bool |
| prefix operator ~ : BinaryInteger |
| prefix operator + : AdditiveArithmetic |
| prefix operator - : SignedNumeric |
| prefix operator ... : Comparable |
| prefix operator ..< : Comparable |
| |
| // Standard infix operators. |
| |
| // "Exponentiative" |
| |
| infix operator << : BitwiseShiftPrecedence, BinaryInteger |
| infix operator &<< : BitwiseShiftPrecedence, FixedWidthInteger |
| infix operator >> : BitwiseShiftPrecedence, BinaryInteger |
| infix operator &>> : BitwiseShiftPrecedence, FixedWidthInteger |
| |
| // "Multiplicative" |
| |
| infix operator * : MultiplicationPrecedence, Numeric |
| infix operator &* : MultiplicationPrecedence, FixedWidthInteger |
| infix operator / : MultiplicationPrecedence, BinaryInteger, FloatingPoint |
| infix operator % : MultiplicationPrecedence, BinaryInteger |
| infix operator & : MultiplicationPrecedence, BinaryInteger |
| |
| // "Additive" |
| |
| infix operator + : AdditionPrecedence, AdditiveArithmetic, String, Array, Strideable |
| infix operator &+ : AdditionPrecedence, FixedWidthInteger |
| infix operator - : AdditionPrecedence, AdditiveArithmetic, Strideable |
| infix operator &- : AdditionPrecedence, FixedWidthInteger |
| infix operator | : AdditionPrecedence, BinaryInteger |
| infix operator ^ : AdditionPrecedence, BinaryInteger |
| |
| // FIXME: is this the right precedence level for "..." ? |
| infix operator ... : RangeFormationPrecedence, Comparable |
| infix operator ..< : RangeFormationPrecedence, Comparable |
| |
| // The cast operators 'as' and 'is' are hardcoded as if they had the |
| // following attributes: |
| // infix operator as : CastingPrecedence |
| |
| // "Coalescing" |
| |
| infix operator ?? : NilCoalescingPrecedence |
| |
| // "Comparative" |
| |
| infix operator < : ComparisonPrecedence, Comparable |
| infix operator <= : ComparisonPrecedence, Comparable |
| infix operator > : ComparisonPrecedence, Comparable |
| infix operator >= : ComparisonPrecedence, Comparable |
| infix operator == : ComparisonPrecedence, Equatable |
| infix operator != : ComparisonPrecedence, Equatable |
| infix operator === : ComparisonPrecedence |
| infix operator !== : ComparisonPrecedence |
| // FIXME: ~= will be built into the compiler. |
| infix operator ~= : ComparisonPrecedence |
| |
| // "Conjunctive" |
| |
| infix operator && : LogicalConjunctionPrecedence, Bool |
| |
| // "Disjunctive" |
| |
| infix operator || : LogicalDisjunctionPrecedence, Bool |
| |
| // User-defined ternary operators are not supported. The ? : operator is |
| // hardcoded as if it had the following attributes: |
| // operator ternary ? : : TernaryPrecedence |
| |
| // User-defined assignment operators are not supported. The = operator is |
| // hardcoded as if it had the following attributes: |
| // infix operator = : AssignmentPrecedence |
| |
| // Compound |
| |
| infix operator *= : AssignmentPrecedence, Numeric |
| infix operator &*= : AssignmentPrecedence, FixedWidthInteger |
| infix operator /= : AssignmentPrecedence, BinaryInteger |
| infix operator %= : AssignmentPrecedence, BinaryInteger |
| infix operator += : AssignmentPrecedence, AdditiveArithmetic, String, Array, Strideable |
| infix operator &+= : AssignmentPrecedence, FixedWidthInteger |
| infix operator -= : AssignmentPrecedence, AdditiveArithmetic, Strideable |
| infix operator &-= : AssignmentPrecedence, FixedWidthInteger |
| infix operator <<= : AssignmentPrecedence, BinaryInteger |
| infix operator &<<= : AssignmentPrecedence, FixedWidthInteger |
| infix operator >>= : AssignmentPrecedence, BinaryInteger |
| infix operator &>>= : AssignmentPrecedence, FixedWidthInteger |
| infix operator &= : AssignmentPrecedence, BinaryInteger |
| infix operator ^= : AssignmentPrecedence, BinaryInteger |
| infix operator |= : AssignmentPrecedence, BinaryInteger |
| |
| // Workaround for <rdar://problem/14011860> SubTLF: Default |
| // implementations in protocols. Library authors should ensure |
| // that this operator never needs to be seen by end-users. See |
| // test/Prototypes/GenericDispatch.swift for a fully documented |
| // example of how this operator is used, and how its use can be hidden |
| // from users. |
| infix operator ~> |