| //===--- Mirror.swift -----------------------------------------------------===// |
| // |
| // This source file is part of the Swift.org open source project |
| // |
| // Copyright (c) 2014 - 2017 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 |
| // |
| //===----------------------------------------------------------------------===// |
| // FIXME: ExistentialCollection needs to be supported before this will work |
| // without the ObjC Runtime. |
| |
| /// Representation of the sub-structure and optional "display style" |
| /// of any arbitrary subject instance. |
| /// |
| /// Describes the parts---such as stored properties, collection |
| /// elements, tuple elements, or the active enumeration case---that |
| /// make up a particular instance. May also supply a "display style" |
| /// property that suggests how this structure might be rendered. |
| /// |
| /// Mirrors are used by playgrounds and the debugger. |
| public struct Mirror { |
| /// Representation of descendant classes that don't override |
| /// `customMirror`. |
| /// |
| /// Note that the effect of this setting goes no deeper than the |
| /// nearest descendant class that overrides `customMirror`, which |
| /// in turn can determine representation of *its* descendants. |
| internal enum _DefaultDescendantRepresentation { |
| /// Generate a default mirror for descendant classes that don't |
| /// override `customMirror`. |
| /// |
| /// This case is the default. |
| case generated |
| |
| /// Suppress the representation of descendant classes that don't |
| /// override `customMirror`. |
| /// |
| /// This option may be useful at the root of a class cluster, where |
| /// implementation details of descendants should generally not be |
| /// visible to clients. |
| case suppressed |
| } |
| |
| /// Representation of ancestor classes. |
| /// |
| /// A `CustomReflectable` class can control how its mirror will |
| /// represent ancestor classes by initializing the mirror with a |
| /// `AncestorRepresentation`. This setting has no effect on mirrors |
| /// reflecting value type instances. |
| public enum AncestorRepresentation { |
| |
| /// Generate a default mirror for all ancestor classes. |
| /// |
| /// This case is the default. |
| /// |
| /// - Note: This option generates default mirrors even for |
| /// ancestor classes that may implement `CustomReflectable`'s |
| /// `customMirror` requirement. To avoid dropping an ancestor class |
| /// customization, an override of `customMirror` should pass |
| /// `ancestorRepresentation: .Customized(super.customMirror)` when |
| /// initializing its `Mirror`. |
| case generated |
| |
| /// Use the nearest ancestor's implementation of `customMirror` to |
| /// create a mirror for that ancestor. Other classes derived from |
| /// such an ancestor are given a default mirror. |
| /// |
| /// The payload for this option should always be |
| /// "`{ super.customMirror }`": |
| /// |
| /// var customMirror: Mirror { |
| /// return Mirror( |
| /// self, |
| /// children: ["someProperty": self.someProperty], |
| /// ancestorRepresentation: .Customized({ super.customMirror })) // <== |
| /// } |
| case customized(() -> Mirror) |
| |
| /// Suppress the representation of all ancestor classes. The |
| /// resulting `Mirror`'s `superclassMirror` is `nil`. |
| case suppressed |
| } |
| |
| /// Reflect upon the given `subject`. |
| /// |
| /// If the dynamic type of `subject` conforms to `CustomReflectable`, |
| /// the resulting mirror is determined by its `customMirror` property. |
| /// Otherwise, the result is generated by the language. |
| /// |
| /// - Note: If the dynamic type of `subject` has value semantics, |
| /// subsequent mutations of `subject` will not observable in |
| /// `Mirror`. In general, though, the observability of such |
| /// mutations is unspecified. |
| public init(reflecting subject: Any) { |
| if case let customized as CustomReflectable = subject { |
| self = customized.customMirror |
| } else { |
| self = Mirror( |
| legacy: _reflect(subject), |
| subjectType: type(of: subject)) |
| } |
| } |
| |
| /// An element of the reflected instance's structure. The optional |
| /// `label` may be used when appropriate, e.g. to represent the name |
| /// of a stored property or of an active `enum` case, and will be |
| /// used for lookup when `String`s are passed to the `descendant` |
| /// method. |
| public typealias Child = (label: String?, value: Any) |
| |
| /// The type used to represent sub-structure. |
| /// |
| /// Depending on your needs, you may find it useful to "upgrade" |
| /// instances of this type to `AnyBidirectionalCollection` or |
| /// `AnyRandomAccessCollection`. For example, to display the last |
| /// 20 children of a mirror if they can be accessed efficiently, you |
| /// might write: |
| /// |
| /// if let b = AnyBidirectionalCollection(someMirror.children) { |
| /// var i = xs.index(b.endIndex, offsetBy: -20, |
| /// limitedBy: b.startIndex) ?? b.startIndex |
| /// while i != xs.endIndex { |
| /// print(b[i]) |
| /// b.formIndex(after: &i) |
| /// } |
| /// } |
| public typealias Children = AnyCollection<Child> |
| |
| /// A suggestion of how a `Mirror`'s `subject` is to be interpreted. |
| /// |
| /// Playgrounds and the debugger will show a representation similar |
| /// to the one used for instances of the kind indicated by the |
| /// `DisplayStyle` case name when the `Mirror` is used for display. |
| public enum DisplayStyle { |
| case `struct`, `class`, `enum`, tuple, optional, collection |
| case dictionary, `set` |
| } |
| |
| static func _noSuperclassMirror() -> Mirror? { return nil } |
| |
| /// Returns the legacy mirror representing the part of `subject` |
| /// corresponding to the superclass of `staticSubclass`. |
| internal static func _legacyMirror( |
| _ subject: AnyObject, asClass targetSuperclass: AnyClass) -> _Mirror? { |
| |
| // get a legacy mirror and the most-derived type |
| var cls: AnyClass = type(of: subject) |
| var clsMirror = _reflect(subject) |
| |
| // Walk up the chain of mirrors/classes until we find staticSubclass |
| while let superclass: AnyClass = _getSuperclass(cls) { |
| guard let superclassMirror = clsMirror._superMirror() else { break } |
| |
| if superclass == targetSuperclass { return superclassMirror } |
| |
| clsMirror = superclassMirror |
| cls = superclass |
| } |
| return nil |
| } |
| |
| @_semantics("optimize.sil.specialize.generic.never") |
| @inline(never) |
| @_versioned |
| internal static func _superclassIterator<Subject>( |
| _ subject: Subject, _ ancestorRepresentation: AncestorRepresentation |
| ) -> () -> Mirror? { |
| |
| if let subjectClass = Subject.self as? AnyClass, |
| let superclass = _getSuperclass(subjectClass) { |
| |
| switch ancestorRepresentation { |
| case .generated: |
| return { |
| self._legacyMirror(_unsafeDowncastToAnyObject(fromAny: subject), asClass: superclass).map { |
| Mirror(legacy: $0, subjectType: superclass) |
| } |
| } |
| case .customized(let makeAncestor): |
| return { |
| Mirror(_unsafeDowncastToAnyObject(fromAny: subject), subjectClass: superclass, |
| ancestor: makeAncestor()) |
| } |
| case .suppressed: |
| break |
| } |
| } |
| return Mirror._noSuperclassMirror |
| } |
| |
| /// Represent `subject` with structure described by `children`, |
| /// using an optional `displayStyle`. |
| /// |
| /// If `subject` is not a class instance, `ancestorRepresentation` |
| /// is ignored. Otherwise, `ancestorRepresentation` determines |
| /// whether ancestor classes will be represented and whether their |
| /// `customMirror` implementations will be used. By default, a |
| /// representation is automatically generated and any `customMirror` |
| /// implementation is bypassed. To prevent bypassing customized |
| /// ancestors, `customMirror` overrides should initialize the |
| /// `Mirror` with: |
| /// |
| /// ancestorRepresentation: .customized({ super.customMirror }) |
| /// |
| /// - Note: The traversal protocol modeled by `children`'s indices |
| /// (`ForwardIndex`, `BidirectionalIndex`, or |
| /// `RandomAccessIndex`) is captured so that the resulting |
| /// `Mirror`'s `children` may be upgraded later. See the failable |
| /// initializers of `AnyBidirectionalCollection` and |
| /// `AnyRandomAccessCollection` for details. |
| public init<Subject, C : Collection>( |
| _ subject: Subject, |
| children: C, |
| displayStyle: DisplayStyle? = nil, |
| ancestorRepresentation: AncestorRepresentation = .generated |
| ) where C.Element == Child |
| // FIXME(ABI) (Revert Where Clauses): Remove these |
| , C.SubSequence : Collection, C.SubSequence.Indices : Collection, C.Indices : Collection |
| { |
| |
| self.subjectType = Subject.self |
| self._makeSuperclassMirror = Mirror._superclassIterator( |
| subject, ancestorRepresentation) |
| |
| self.children = Children(children) |
| self.displayStyle = displayStyle |
| self._defaultDescendantRepresentation |
| = subject is CustomLeafReflectable ? .suppressed : .generated |
| } |
| |
| /// Represent `subject` with child values given by |
| /// `unlabeledChildren`, using an optional `displayStyle`. The |
| /// result's child labels will all be `nil`. |
| /// |
| /// This initializer is especially useful for the mirrors of |
| /// collections, e.g.: |
| /// |
| /// extension MyArray : CustomReflectable { |
| /// var customMirror: Mirror { |
| /// return Mirror(self, unlabeledChildren: self, displayStyle: .collection) |
| /// } |
| /// } |
| /// |
| /// If `subject` is not a class instance, `ancestorRepresentation` |
| /// is ignored. Otherwise, `ancestorRepresentation` determines |
| /// whether ancestor classes will be represented and whether their |
| /// `customMirror` implementations will be used. By default, a |
| /// representation is automatically generated and any `customMirror` |
| /// implementation is bypassed. To prevent bypassing customized |
| /// ancestors, `customMirror` overrides should initialize the |
| /// `Mirror` with: |
| /// |
| /// ancestorRepresentation: .Customized({ super.customMirror }) |
| /// |
| /// - Note: The traversal protocol modeled by `children`'s indices |
| /// (`ForwardIndex`, `BidirectionalIndex`, or |
| /// `RandomAccessIndex`) is captured so that the resulting |
| /// `Mirror`'s `children` may be upgraded later. See the failable |
| /// initializers of `AnyBidirectionalCollection` and |
| /// `AnyRandomAccessCollection` for details. |
| public init<Subject, C : Collection>( |
| _ subject: Subject, |
| unlabeledChildren: C, |
| displayStyle: DisplayStyle? = nil, |
| ancestorRepresentation: AncestorRepresentation = .generated |
| ) |
| // FIXME(ABI) (Revert Where Clauses): Remove these two clauses |
| where C.SubSequence : Collection, C.Indices : Collection |
| { |
| |
| self.subjectType = Subject.self |
| self._makeSuperclassMirror = Mirror._superclassIterator( |
| subject, ancestorRepresentation) |
| |
| let lazyChildren = |
| unlabeledChildren.lazy.map { Child(label: nil, value: $0) } |
| self.children = Children(lazyChildren) |
| |
| self.displayStyle = displayStyle |
| self._defaultDescendantRepresentation |
| = subject is CustomLeafReflectable ? .suppressed : .generated |
| } |
| |
| /// Represent `subject` with labeled structure described by |
| /// `children`, using an optional `displayStyle`. |
| /// |
| /// Pass a dictionary literal with `String` keys as `children`. Be |
| /// aware that although an *actual* `Dictionary` is |
| /// arbitrarily-ordered, the ordering of the `Mirror`'s `children` |
| /// will exactly match that of the literal you pass. |
| /// |
| /// If `subject` is not a class instance, `ancestorRepresentation` |
| /// is ignored. Otherwise, `ancestorRepresentation` determines |
| /// whether ancestor classes will be represented and whether their |
| /// `customMirror` implementations will be used. By default, a |
| /// representation is automatically generated and any `customMirror` |
| /// implementation is bypassed. To prevent bypassing customized |
| /// ancestors, `customMirror` overrides should initialize the |
| /// `Mirror` with: |
| /// |
| /// ancestorRepresentation: .customized({ super.customMirror }) |
| /// |
| /// - Note: The resulting `Mirror`'s `children` may be upgraded to |
| /// `AnyRandomAccessCollection` later. See the failable |
| /// initializers of `AnyBidirectionalCollection` and |
| /// `AnyRandomAccessCollection` for details. |
| public init<Subject>( |
| _ subject: Subject, |
| children: DictionaryLiteral<String, Any>, |
| displayStyle: DisplayStyle? = nil, |
| ancestorRepresentation: AncestorRepresentation = .generated |
| ) { |
| self.subjectType = Subject.self |
| self._makeSuperclassMirror = Mirror._superclassIterator( |
| subject, ancestorRepresentation) |
| |
| let lazyChildren = children.lazy.map { Child(label: $0.0, value: $0.1) } |
| self.children = Children(lazyChildren) |
| |
| self.displayStyle = displayStyle |
| self._defaultDescendantRepresentation |
| = subject is CustomLeafReflectable ? .suppressed : .generated |
| } |
| |
| /// The static type of the subject being reflected. |
| /// |
| /// This type may differ from the subject's dynamic type when `self` |
| /// is the `superclassMirror` of another mirror. |
| public let subjectType: Any.Type |
| |
| /// A collection of `Child` elements describing the structure of the |
| /// reflected subject. |
| public let children: Children |
| |
| /// Suggests a display style for the reflected subject. |
| public let displayStyle: DisplayStyle? |
| |
| public var superclassMirror: Mirror? { |
| return _makeSuperclassMirror() |
| } |
| |
| internal let _makeSuperclassMirror: () -> Mirror? |
| internal let _defaultDescendantRepresentation: _DefaultDescendantRepresentation |
| } |
| |
| /// A type that explicitly supplies its own mirror. |
| /// |
| /// You can create a mirror for any type using the `Mirror(reflect:)` |
| /// initializer, but if you are not satisfied with the mirror supplied for |
| /// your type by default, you can make it conform to `CustomReflectable` and |
| /// return a custom `Mirror` instance. |
| public protocol CustomReflectable { |
| /// The custom mirror for this instance. |
| /// |
| /// If this type has value semantics, the mirror should be unaffected by |
| /// subsequent mutations of the instance. |
| var customMirror: Mirror { get } |
| } |
| |
| /// A type that explicitly supplies its own mirror, but whose |
| /// descendant classes are not represented in the mirror unless they |
| /// also override `customMirror`. |
| public protocol CustomLeafReflectable : CustomReflectable {} |
| |
| //===--- Addressing -------------------------------------------------------===// |
| |
| /// A protocol for legitimate arguments to `Mirror`'s `descendant` |
| /// method. |
| /// |
| /// Do not declare new conformances to this protocol; they will not |
| /// work as expected. |
| // FIXME(ABI)#49 (Sealed Protocols): this protocol should be "non-open" and you shouldn't be able to |
| // create conformances. |
| public protocol MirrorPath {} |
| extension Int : MirrorPath {} |
| extension String : MirrorPath {} |
| |
| extension Mirror { |
| internal struct _Dummy : CustomReflectable { |
| var mirror: Mirror |
| var customMirror: Mirror { return mirror } |
| } |
| |
| /// Return a specific descendant of the reflected subject, or `nil` |
| /// Returns a specific descendant of the reflected subject, or `nil` |
| /// if no such descendant exists. |
| /// |
| /// A `String` argument selects the first `Child` with a matching label. |
| /// An integer argument *n* select the *n*th `Child`. For example: |
| /// |
| /// var d = Mirror(reflecting: x).descendant(1, "two", 3) |
| /// |
| /// is equivalent to: |
| /// |
| /// var d = nil |
| /// let children = Mirror(reflecting: x).children |
| /// if let p0 = children.index(children.startIndex, |
| /// offsetBy: 1, limitedBy: children.endIndex) { |
| /// let grandChildren = Mirror(reflecting: children[p0].value).children |
| /// SeekTwo: for g in grandChildren { |
| /// if g.label == "two" { |
| /// let greatGrandChildren = Mirror(reflecting: g.value).children |
| /// if let p1 = greatGrandChildren.index( |
| /// greatGrandChildren.startIndex, |
| /// offsetBy: 3, limitedBy: greatGrandChildren.endIndex) { |
| /// d = greatGrandChildren[p1].value |
| /// } |
| /// break SeekTwo |
| /// } |
| /// } |
| /// } |
| /// |
| /// As you can see, complexity for each element of the argument list |
| /// depends on the argument type and capabilities of the collection |
| /// used to initialize the corresponding subject's parent's mirror. |
| /// Each `String` argument results in a linear search. In short, |
| /// this function is suitable for exploring the structure of a |
| /// `Mirror` in a REPL or playground, but don't expect it to be |
| /// efficient. |
| public func descendant( |
| _ first: MirrorPath, _ rest: MirrorPath... |
| ) -> Any? { |
| var result: Any = _Dummy(mirror: self) |
| for e in [first] + rest { |
| let children = Mirror(reflecting: result).children |
| let position: Children.Index |
| if case let label as String = e { |
| position = children.index { $0.label == label } ?? children.endIndex |
| } |
| else if let offset = (e as? Int).map({ Int64($0) }) ?? (e as? Int64) { |
| position = children.index(children.startIndex, |
| offsetBy: offset, |
| limitedBy: children.endIndex) ?? children.endIndex |
| } |
| else { |
| _preconditionFailure( |
| "Someone added a conformance to MirrorPath; that privilege is reserved to the standard library") |
| } |
| if position == children.endIndex { return nil } |
| result = children[position].value |
| } |
| return result |
| } |
| } |
| |
| //===--- Legacy _Mirror Support -------------------------------------------===// |
| extension Mirror.DisplayStyle { |
| /// Construct from a legacy `_MirrorDisposition` |
| internal init?(legacy: _MirrorDisposition) { |
| switch legacy { |
| case .`struct`: self = .`struct` |
| case .`class`: self = .`class` |
| case .`enum`: self = .`enum` |
| case .tuple: self = .tuple |
| case .aggregate: return nil |
| case .indexContainer: self = .collection |
| case .keyContainer: self = .dictionary |
| case .membershipContainer: self = .`set` |
| case .container: preconditionFailure("unused!") |
| case .optional: self = .optional |
| case .objCObject: self = .`class` |
| } |
| } |
| } |
| |
| internal func _isClassSuperMirror(_ t: Any.Type) -> Bool { |
| #if _runtime(_ObjC) |
| return t == _ClassSuperMirror.self || t == _ObjCSuperMirror.self |
| #else |
| return t == _ClassSuperMirror.self |
| #endif |
| } |
| |
| extension _Mirror { |
| internal func _superMirror() -> _Mirror? { |
| if self.count > 0 { |
| let childMirror = self[0].1 |
| if _isClassSuperMirror(type(of: childMirror)) { |
| return childMirror |
| } |
| } |
| return nil |
| } |
| } |
| |
| /// When constructed using the legacy reflection infrastructure, the |
| /// resulting `Mirror`'s `children` collection will always be |
| /// upgradable to `AnyRandomAccessCollection` even if it doesn't |
| /// exhibit appropriate performance. To avoid this pitfall, convert |
| /// mirrors to use the new style, which only present forward |
| /// traversal in general. |
| internal extension Mirror { |
| /// An adapter that represents a legacy `_Mirror`'s children as |
| /// a `Collection` with integer `Index`. Note that the performance |
| /// characteristics of the underlying `_Mirror` may not be |
| /// appropriate for random access! To avoid this pitfall, convert |
| /// mirrors to use the new style, which only present forward |
| /// traversal in general. |
| internal struct LegacyChildren : RandomAccessCollection { |
| typealias Indices = CountableRange<Int> |
| |
| init(_ oldMirror: _Mirror) { |
| self._oldMirror = oldMirror |
| } |
| |
| var startIndex: Int { |
| return _oldMirror._superMirror() == nil ? 0 : 1 |
| } |
| |
| var endIndex: Int { return _oldMirror.count } |
| |
| subscript(position: Int) -> Child { |
| let (label, childMirror) = _oldMirror[position] |
| return (label: label, value: childMirror.value) |
| } |
| |
| internal let _oldMirror: _Mirror |
| } |
| |
| /// Initialize for a view of `subject` as `subjectClass`. |
| /// |
| /// - parameter ancestor: A Mirror for a (non-strict) ancestor of |
| /// `subjectClass`, to be injected into the resulting hierarchy. |
| /// |
| /// - parameter legacy: Either `nil`, or a legacy mirror for `subject` |
| /// as `subjectClass`. |
| internal init( |
| _ subject: AnyObject, |
| subjectClass: AnyClass, |
| ancestor: Mirror, |
| legacy legacyMirror: _Mirror? = nil |
| ) { |
| if ancestor.subjectType == subjectClass |
| || ancestor._defaultDescendantRepresentation == .suppressed { |
| self = ancestor |
| } |
| else { |
| let legacyMirror = legacyMirror ?? Mirror._legacyMirror( |
| subject, asClass: subjectClass)! |
| |
| self = Mirror( |
| legacy: legacyMirror, |
| subjectType: subjectClass, |
| makeSuperclassMirror: { |
| _getSuperclass(subjectClass).map { |
| Mirror( |
| subject, |
| subjectClass: $0, |
| ancestor: ancestor, |
| legacy: legacyMirror._superMirror()) |
| } |
| }) |
| } |
| } |
| |
| internal init( |
| legacy legacyMirror: _Mirror, |
| subjectType: Any.Type, |
| makeSuperclassMirror: (() -> Mirror?)? = nil |
| ) { |
| if let makeSuperclassMirror = makeSuperclassMirror { |
| self._makeSuperclassMirror = makeSuperclassMirror |
| } |
| else if let subjectSuperclass = _getSuperclass(subjectType) { |
| self._makeSuperclassMirror = { |
| legacyMirror._superMirror().map { |
| Mirror(legacy: $0, subjectType: subjectSuperclass) } |
| } |
| } |
| else { |
| self._makeSuperclassMirror = Mirror._noSuperclassMirror |
| } |
| self.subjectType = subjectType |
| self.children = Children(LegacyChildren(legacyMirror)) |
| self.displayStyle = DisplayStyle(legacy: legacyMirror.disposition) |
| self._defaultDescendantRepresentation = .generated |
| } |
| } |
| |
| //===--- QuickLooks -------------------------------------------------------===// |
| |
| /// The sum of types that can be used as a Quick Look representation. |
| public enum PlaygroundQuickLook { |
| /// Plain text. |
| case text(String) |
| |
| /// An integer numeric value. |
| case int(Int64) |
| |
| /// An unsigned integer numeric value. |
| case uInt(UInt64) |
| |
| /// A single precision floating-point numeric value. |
| case float(Float32) |
| |
| /// A double precision floating-point numeric value. |
| case double(Float64) |
| |
| // FIXME: Uses an Any to avoid coupling a particular Cocoa type. |
| /// An image. |
| case image(Any) |
| |
| // FIXME: Uses an Any to avoid coupling a particular Cocoa type. |
| /// A sound. |
| case sound(Any) |
| |
| // FIXME: Uses an Any to avoid coupling a particular Cocoa type. |
| /// A color. |
| case color(Any) |
| |
| // FIXME: Uses an Any to avoid coupling a particular Cocoa type. |
| /// A bezier path. |
| case bezierPath(Any) |
| |
| // FIXME: Uses an Any to avoid coupling a particular Cocoa type. |
| /// An attributed string. |
| case attributedString(Any) |
| |
| // FIXME: Uses explicit coordinates to avoid coupling a particular Cocoa type. |
| /// A rectangle. |
| case rectangle(Float64, Float64, Float64, Float64) |
| |
| // FIXME: Uses explicit coordinates to avoid coupling a particular Cocoa type. |
| /// A point. |
| case point(Float64, Float64) |
| |
| // FIXME: Uses explicit coordinates to avoid coupling a particular Cocoa type. |
| /// A size. |
| case size(Float64, Float64) |
| |
| /// A boolean value. |
| case bool(Bool) |
| |
| // FIXME: Uses explicit values to avoid coupling a particular Cocoa type. |
| /// A range. |
| case range(Int64, Int64) |
| |
| // FIXME: Uses an Any to avoid coupling a particular Cocoa type. |
| /// A GUI view. |
| case view(Any) |
| |
| // FIXME: Uses an Any to avoid coupling a particular Cocoa type. |
| /// A graphical sprite. |
| case sprite(Any) |
| |
| /// A Uniform Resource Locator. |
| case url(String) |
| |
| /// Raw data that has already been encoded in a format the IDE understands. |
| case _raw([UInt8], String) |
| } |
| |
| extension PlaygroundQuickLook { |
| /// Initialize for the given `subject`. |
| /// |
| /// If the dynamic type of `subject` conforms to |
| /// `CustomPlaygroundQuickLookable`, returns the result of calling |
| /// its `customPlaygroundQuickLook` property. Otherwise, returns |
| /// a `PlaygroundQuickLook` synthesized for `subject` by the |
| /// language. Note that in some cases the result may be |
| /// `.Text(String(reflecting: subject))`. |
| /// |
| /// - Note: If the dynamic type of `subject` has value semantics, |
| /// subsequent mutations of `subject` will not observable in |
| /// `Mirror`. In general, though, the observability of such |
| /// mutations is unspecified. |
| public init(reflecting subject: Any) { |
| if let customized = subject as? CustomPlaygroundQuickLookable { |
| self = customized.customPlaygroundQuickLook |
| } |
| else if let customized = subject as? _DefaultCustomPlaygroundQuickLookable { |
| self = customized._defaultCustomPlaygroundQuickLook |
| } |
| else { |
| if let q = _reflect(subject).quickLookObject { |
| self = q |
| } |
| else { |
| self = .text(String(reflecting: subject)) |
| } |
| } |
| } |
| } |
| |
| /// A type that explicitly supplies its own playground Quick Look. |
| /// |
| /// A Quick Look can be created for an instance of any type by using the |
| /// `PlaygroundQuickLook(reflecting:)` initializer. If you are not satisfied |
| /// with the representation supplied for your type by default, you can make it |
| /// conform to the `CustomPlaygroundQuickLookable` protocol and provide a |
| /// custom `PlaygroundQuickLook` instance. |
| public protocol CustomPlaygroundQuickLookable { |
| /// A custom playground Quick Look for this instance. |
| /// |
| /// If this type has value semantics, the `PlaygroundQuickLook` instance |
| /// should be unaffected by subsequent mutations. |
| var customPlaygroundQuickLook: PlaygroundQuickLook { get } |
| } |
| |
| |
| // A workaround for <rdar://problem/26182650> |
| // FIXME(ABI)#50 (Dynamic Dispatch for Class Extensions) though not if it moves out of stdlib. |
| public protocol _DefaultCustomPlaygroundQuickLookable { |
| var _defaultCustomPlaygroundQuickLook: PlaygroundQuickLook { get } |
| } |
| |
| //===--- General Utilities ------------------------------------------------===// |
| // This component could stand alone, but is used in Mirror's public interface. |
| |
| /// A lightweight collection of key-value pairs. |
| /// |
| /// Use a `DictionaryLiteral` instance when you need an ordered collection of |
| /// key-value pairs and don't require the fast key lookup that the |
| /// `Dictionary` type provides. Unlike key-value pairs in a true dictionary, |
| /// neither the key nor the value of a `DictionaryLiteral` instance must |
| /// conform to the `Hashable` protocol. |
| /// |
| /// You initialize a `DictionaryLiteral` instance using a Swift dictionary |
| /// literal. Besides maintaining the order of the original dictionary literal, |
| /// `DictionaryLiteral` also allows duplicates keys. For example: |
| /// |
| /// let recordTimes: DictionaryLiteral = ["Florence Griffith-Joyner": 10.49, |
| /// "Evelyn Ashford": 10.76, |
| /// "Evelyn Ashford": 10.79, |
| /// "Marlies Gohr": 10.81] |
| /// print(recordTimes.first!) |
| /// // Prints "("Florence Griffith-Joyner", 10.49)" |
| /// |
| /// Some operations that are efficient on a dictionary are slower when using |
| /// `DictionaryLiteral`. In particular, to find the value matching a key, you |
| /// must search through every element of the collection. The call to |
| /// `index(where:)` in the following example must traverse the whole |
| /// collection to find the element that matches the predicate: |
| /// |
| /// let runner = "Marlies Gohr" |
| /// if let index = recordTimes.index(where: { $0.0 == runner }) { |
| /// let time = recordTimes[index].1 |
| /// print("\(runner) set a 100m record of \(time) seconds.") |
| /// } else { |
| /// print("\(runner) couldn't be found in the records.") |
| /// } |
| /// // Prints "Marlies Gohr set a 100m record of 10.81 seconds." |
| /// |
| /// Dictionary Literals as Function Parameters |
| /// ------------------------------------------ |
| /// |
| /// When calling a function with a `DictionaryLiteral` parameter, you can pass |
| /// a Swift dictionary literal without causing a `Dictionary` to be created. |
| /// This capability can be especially important when the order of elements in |
| /// the literal is significant. |
| /// |
| /// For example, you could create an `IntPairs` structure that holds a list of |
| /// two-integer tuples and use an initializer that accepts a |
| /// `DictionaryLiteral` instance. |
| /// |
| /// struct IntPairs { |
| /// var elements: [(Int, Int)] |
| /// |
| /// init(_ elements: DictionaryLiteral<Int, Int>) { |
| /// self.elements = Array(elements) |
| /// } |
| /// } |
| /// |
| /// When you're ready to create a new `IntPairs` instance, use a dictionary |
| /// literal as the parameter to the `IntPairs` initializer. The |
| /// `DictionaryLiteral` instance preserves the order of the elements as |
| /// passed. |
| /// |
| /// let pairs = IntPairs([1: 2, 1: 1, 3: 4, 2: 1]) |
| /// print(pairs.elements) |
| /// // Prints "[(1, 2), (1, 1), (3, 4), (2, 1)]" |
| public struct DictionaryLiteral<Key, Value> : ExpressibleByDictionaryLiteral { |
| /// Creates a new `DictionaryLiteral` instance from the given dictionary |
| /// literal. |
| /// |
| /// The order of the key-value pairs is kept intact in the resulting |
| /// `DictionaryLiteral` instance. |
| public init(dictionaryLiteral elements: (Key, Value)...) { |
| self._elements = elements |
| } |
| internal let _elements: [(Key, Value)] |
| } |
| |
| /// `Collection` conformance that allows `DictionaryLiteral` to |
| /// interoperate with the rest of the standard library. |
| extension DictionaryLiteral : RandomAccessCollection { |
| public typealias Indices = CountableRange<Int> |
| |
| /// The position of the first element in a nonempty collection. |
| /// |
| /// If the `DictionaryLiteral` instance is empty, `startIndex` is equal to |
| /// `endIndex`. |
| public var startIndex: Int { return 0 } |
| |
| /// The collection's "past the end" position---that is, the position one |
| /// greater than the last valid subscript argument. |
| /// |
| /// If the `DictionaryLiteral` instance is empty, `endIndex` is equal to |
| /// `startIndex`. |
| public var endIndex: Int { return _elements.endIndex } |
| |
| // FIXME(ABI)#174 (Type checker): a typealias is needed to prevent <rdar://20248032> |
| /// The element type of a `DictionaryLiteral`: a tuple containing an |
| /// individual key-value pair. |
| public typealias Element = (key: Key, value: Value) |
| |
| /// Accesses the element at the specified position. |
| /// |
| /// - Parameter position: The position of the element to access. `position` |
| /// must be a valid index of the collection that is not equal to the |
| /// `endIndex` property. |
| /// - Returns: The key-value pair at position `position`. |
| public subscript(position: Int) -> Element { |
| return _elements[position] |
| } |
| } |
| |
| extension String { |
| /// Creates a string representing the given value. |
| /// |
| /// Use this initializer to convert an instance of any type to its preferred |
| /// representation as a `String` instance. The initializer creates the |
| /// string representation of `instance` in one of the following ways, |
| /// depending on its protocol conformance: |
| /// |
| /// - If `instance` conforms to the `TextOutputStreamable` protocol, the |
| /// result is obtained by calling `instance.write(to: s)` on an empty |
| /// string `s`. |
| /// - If `instance` conforms to the `CustomStringConvertible` protocol, the |
| /// result is `instance.description`. |
| /// - If `instance` conforms to the `CustomDebugStringConvertible` protocol, |
| /// the result is `instance.debugDescription`. |
| /// - An unspecified result is supplied automatically by the Swift standard |
| /// library. |
| /// |
| /// For example, this custom `Point` struct uses the default representation |
| /// supplied by the standard library. |
| /// |
| /// struct Point { |
| /// let x: Int, y: Int |
| /// } |
| /// |
| /// let p = Point(x: 21, y: 30) |
| /// print(String(describing: p)) |
| /// // Prints "Point(x: 21, y: 30)" |
| /// |
| /// After adding `CustomStringConvertible` conformance by implementing the |
| /// `description` property, `Point` provides its own custom representation. |
| /// |
| /// extension Point: CustomStringConvertible { |
| /// var description: String { |
| /// return "(\(x), \(y))" |
| /// } |
| /// } |
| /// |
| /// print(String(describing: p)) |
| /// // Prints "(21, 30)" |
| public init<Subject>(describing instance: Subject) { |
| self.init() |
| _print_unlocked(instance, &self) |
| } |
| |
| /// Creates a string with a detailed representation of the given value, |
| /// suitable for debugging. |
| /// |
| /// Use this initializer to convert an instance of any type to its custom |
| /// debugging representation. The initializer creates the string |
| /// representation of `instance` in one of the following ways, depending on |
| /// its protocol conformance: |
| /// |
| /// - If `subject` conforms to the `CustomDebugStringConvertible` protocol, |
| /// the result is `subject.debugDescription`. |
| /// - If `subject` conforms to the `CustomStringConvertible` protocol, the |
| /// result is `subject.description`. |
| /// - If `subject` conforms to the `TextOutputStreamable` protocol, the |
| /// result is obtained by calling `subject.write(to: s)` on an empty |
| /// string `s`. |
| /// - An unspecified result is supplied automatically by the Swift standard |
| /// library. |
| /// |
| /// For example, this custom `Point` struct uses the default representation |
| /// supplied by the standard library. |
| /// |
| /// struct Point { |
| /// let x: Int, y: Int |
| /// } |
| /// |
| /// let p = Point(x: 21, y: 30) |
| /// print(String(reflecting: p)) |
| /// // Prints "p: Point = { |
| /// // x = 21 |
| /// // y = 30 |
| /// // }" |
| /// |
| /// After adding `CustomDebugStringConvertible` conformance by implementing |
| /// the `debugDescription` property, `Point` provides its own custom |
| /// debugging representation. |
| /// |
| /// extension Point: CustomDebugStringConvertible { |
| /// var debugDescription: String { |
| /// return "Point(x: \(x), y: \(y))" |
| /// } |
| /// } |
| /// |
| /// print(String(reflecting: p)) |
| /// // Prints "Point(x: 21, y: 30)" |
| public init<Subject>(reflecting subject: Subject) { |
| self.init() |
| _debugPrint_unlocked(subject, &self) |
| } |
| } |
| |
| /// Reflection for `Mirror` itself. |
| extension Mirror : CustomStringConvertible { |
| public var description: String { |
| return "Mirror for \(self.subjectType)" |
| } |
| } |
| |
| extension Mirror : CustomReflectable { |
| public var customMirror: Mirror { |
| return Mirror(self, children: [:]) |
| } |
| } |