//===----------------------------------------------------------------------===// // // This source file is part of the Swift.org open source project // // Copyright (c) 2014 - 2016 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 // //===----------------------------------------------------------------------===// /// Dumps an object's contents using its mirror to the specified output stream. @discardableResult public func dump( _ value: T, to target: inout TargetStream, name: String? = nil, indent: Int = 0, maxDepth: Int = .max, maxItems: Int = .max ) -> T { var maxItemCounter = maxItems var visitedItems = [ObjectIdentifier : Int]() target._lock() defer { target._unlock() } _dump_unlocked( value, to: &target, name: name, indent: indent, maxDepth: maxDepth, maxItemCounter: &maxItemCounter, visitedItems: &visitedItems) return value } /// Dumps an object's contents using its mirror to standard output. @discardableResult public func dump( _ value: T, name: String? = nil, indent: Int = 0, maxDepth: Int = .max, maxItems: Int = .max ) -> T { var stdoutStream = _Stdout() return dump( value, to: &stdoutStream, name: name, indent: indent, maxDepth: maxDepth, maxItems: maxItems) } /// Dump an object's contents. User code should use dump(). internal func _dump_unlocked( _ value: Any, to target: inout TargetStream, name: String?, indent: Int, maxDepth: Int, maxItemCounter: inout Int, visitedItems: inout [ObjectIdentifier : Int] ) { guard maxItemCounter > 0 else { return } maxItemCounter -= 1 for _ in 0.. 0 else { return } if let superclassMirror = mirror.superclassMirror { _dumpSuperclass_unlocked( mirror: superclassMirror, to: &target, indent: indent + 2, maxDepth: maxDepth - 1, maxItemCounter: &maxItemCounter, visitedItems: &visitedItems) } var currentIndex = mirror.children.startIndex for i in 0.. 0 { target.write(" more") } if remainder == 1 { target.write(" child)\n") } else { target.write(" children)\n") } return } let (name, child) = mirror.children[currentIndex] mirror.children.formIndex(after: ¤tIndex) _dump_unlocked( child, to: &target, name: name, indent: indent + 2, maxDepth: maxDepth - 1, maxItemCounter: &maxItemCounter, visitedItems: &visitedItems) } } /// Dump information about an object's superclass, given a mirror reflecting /// that superclass. internal func _dumpSuperclass_unlocked( mirror: Mirror, to target: inout TargetStream, indent: Int, maxDepth: Int, maxItemCounter: inout Int, visitedItems: inout [ObjectIdentifier : Int] ) { guard maxItemCounter > 0 else { return } maxItemCounter -= 1 for _ in 0.. 0 else { return } if let superclassMirror = mirror.superclassMirror { _dumpSuperclass_unlocked( mirror: superclassMirror, to: &target, indent: indent + 2, maxDepth: maxDepth - 1, maxItemCounter: &maxItemCounter, visitedItems: &visitedItems) } var currentIndex = mirror.children.startIndex for i in 0.. 0 { target.write(" more") } if remainder == 1 { target.write(" child)\n") } else { target.write(" children)\n") } return } let (name, child) = mirror.children[currentIndex] mirror.children.formIndex(after: ¤tIndex) _dump_unlocked( child, to: &target, name: name, indent: indent + 2, maxDepth: maxDepth - 1, maxItemCounter: &maxItemCounter, visitedItems: &visitedItems) } }