From 46ef62db6ec8fb5668d3a7b6e5ed935f8af30d6a Mon Sep 17 00:00:00 2001 From: Dmitri Gribenko Date: Fri, 12 Aug 2016 00:49:23 -0700 Subject: [PATCH 1/2] stdlib: move non-legacy parts of Reflection.swift into separate files --- stdlib/public/core/CMakeLists.txt | 2 + stdlib/public/core/Dump.swift | 219 +++++++++++++++ stdlib/public/core/GroupInfo.json | 8 +- stdlib/public/core/ObjectIdentifier.swift | 125 +++++++++ stdlib/public/core/Reflection.swift | 319 ---------------------- 5 files changed, 351 insertions(+), 322 deletions(-) create mode 100644 stdlib/public/core/Dump.swift create mode 100644 stdlib/public/core/ObjectIdentifier.swift diff --git a/stdlib/public/core/CMakeLists.txt b/stdlib/public/core/CMakeLists.txt index 1460997880fd8..17df73825e86c 100644 --- a/stdlib/public/core/CMakeLists.txt +++ b/stdlib/public/core/CMakeLists.txt @@ -45,6 +45,7 @@ set(SWIFTLIB_ESSENTIAL CTypes.swift DebuggerSupport.swift DropWhile.swift.gyb + Dump.swift EmptyCollection.swift Equatable.swift ErrorType.swift @@ -84,6 +85,7 @@ set(SWIFTLIB_ESSENTIAL MutableCollection.swift NewtypeWrapper.swift.gyb ObjCMirrors.swift + ObjectIdentifier.swift Optional.swift OptionSet.swift OutputStream.swift diff --git a/stdlib/public/core/Dump.swift b/stdlib/public/core/Dump.swift new file mode 100644 index 0000000000000..f322ac3306c26 --- /dev/null +++ b/stdlib/public/core/Dump.swift @@ -0,0 +1,219 @@ +//===----------------------------------------------------------------------===// +// +// 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 http://swift.org/LICENSE.txt for license information +// See http://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) + } +} + diff --git a/stdlib/public/core/GroupInfo.json b/stdlib/public/core/GroupInfo.json index 2d931ac90b917..207153b32b92b 100644 --- a/stdlib/public/core/GroupInfo.json +++ b/stdlib/public/core/GroupInfo.json @@ -95,10 +95,12 @@ "MemoryLayout.swift" ], "Reflection": [ - "Mirrors.swift", + "Dump.swift", "Mirror.swift", - "Reflection.swift", - "ObjCMirrors.swift" + "Mirrors.swift", + "ObjCMirrors.swift", + "ObjectIdentifier.swift", + "Reflection.swift" ], "Math": [ "SetAlgebra.swift", diff --git a/stdlib/public/core/ObjectIdentifier.swift b/stdlib/public/core/ObjectIdentifier.swift new file mode 100644 index 0000000000000..2bc0c7054e137 --- /dev/null +++ b/stdlib/public/core/ObjectIdentifier.swift @@ -0,0 +1,125 @@ +//===----------------------------------------------------------------------===// +// +// 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 http://swift.org/LICENSE.txt for license information +// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// + +/// A unique identifier for a class instance or metatype. +/// +/// In Swift, only class instances and metatypes have unique identities. There +/// is no notion of identity for structs, enums, functions, or tuples. +public struct ObjectIdentifier : Hashable { + internal let _value: Builtin.RawPointer + + // FIXME: Better hashing algorithm + /// The identifier's hash value. + /// + /// 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. + /// + /// - SeeAlso: `Hashable` + public var hashValue: Int { + return Int(Builtin.ptrtoint_Word(_value)) + } + + /// Creates an instance that uniquely identifies the given class instance. + /// + /// The following example creates an example class `A` and compares instances + /// of the class using their object identifiers and the identical-to + /// operator (`===`): + /// + /// class IntegerRef { + /// let value: Int + /// init(_ value: Int) { + /// self.value = value + /// } + /// } + /// + /// let x = IntegerRef(10) + /// let y = x + /// + /// print(ObjectIdentifier(x) == ObjectIdentifier(y)) + /// // Prints "true" + /// print(x === y) + /// // Prints "true" + /// + /// let z = IntegerRef(10) + /// print(ObjectIdentifier(x) == ObjectIdentifier(z)) + /// // Prints "false" + /// print(x === z) + /// // Prints "false" + /// + /// - Parameter x: An instance of a class. + public init(_ x: AnyObject) { + self._value = Builtin.bridgeToRawPointer(x) + } + + /// Creates an instance that uniquely identifies the given metatype. + /// + /// - Parameter: A metatype. + public init(_ x: Any.Type) { + self._value = unsafeBitCast(x, to: Builtin.RawPointer.self) + } +} + +extension ObjectIdentifier : CustomDebugStringConvertible { + /// A textual representation of the identifier, suitable for debugging. + public var debugDescription: String { + return "ObjectIdentifier(\(_rawPointerToString(_value)))" + } +} + +extension ObjectIdentifier : Comparable { + public static func < (lhs: ObjectIdentifier, rhs: ObjectIdentifier) -> Bool { + return UInt(bitPattern: lhs) < UInt(bitPattern: rhs) + } + + public static func == (x: ObjectIdentifier, y: ObjectIdentifier) -> Bool { + return Bool(Builtin.cmp_eq_RawPointer(x._value, y._value)) + } +} + +extension UInt { + /// Creates an integer that captures the full value of the given object + /// identifier. + public init(bitPattern objectID: ObjectIdentifier) { + self.init(Builtin.ptrtoint_Word(objectID._value)) + } +} + +extension Int { + /// Creates an integer that captures the full value of the given object + /// identifier. + public init(bitPattern objectID: ObjectIdentifier) { + self.init(bitPattern: UInt(bitPattern: objectID)) + } +} + +extension ObjectIdentifier { + @available(*, unavailable, message: "use the 'UInt(_:)' initializer") + public var uintValue: UInt { + Builtin.unreachable() + } +} + +extension UInt { + @available(*, unavailable, renamed: "init(bitPattern:)") + public init(_ objectID: ObjectIdentifier) { + Builtin.unreachable() + } +} + +extension Int { + @available(*, unavailable, renamed: "init(bitPattern:)") + public init(_ objectID: ObjectIdentifier) { + Builtin.unreachable() + } +} + diff --git a/stdlib/public/core/Reflection.swift b/stdlib/public/core/Reflection.swift index ea78719710cd1..0c68b285df69b 100644 --- a/stdlib/public/core/Reflection.swift +++ b/stdlib/public/core/Reflection.swift @@ -10,98 +10,6 @@ // //===----------------------------------------------------------------------===// -/// A unique identifier for a class instance or metatype. -/// -/// In Swift, only class instances and metatypes have unique identities. There -/// is no notion of identity for structs, enums, functions, or tuples. -public struct ObjectIdentifier : Hashable { - internal let _value: Builtin.RawPointer - - // FIXME: Better hashing algorithm - /// The identifier's hash value. - /// - /// 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. - /// - /// - SeeAlso: `Hashable` - public var hashValue: Int { - return Int(Builtin.ptrtoint_Word(_value)) - } - - /// Creates an instance that uniquely identifies the given class instance. - /// - /// The following example creates an example class `A` and compares instances - /// of the class using their object identifiers and the identical-to - /// operator (`===`): - /// - /// class IntegerRef { - /// let value: Int - /// init(_ value: Int) { - /// self.value = value - /// } - /// } - /// - /// let x = IntegerRef(10) - /// let y = x - /// - /// print(ObjectIdentifier(x) == ObjectIdentifier(y)) - /// // Prints "true" - /// print(x === y) - /// // Prints "true" - /// - /// let z = IntegerRef(10) - /// print(ObjectIdentifier(x) == ObjectIdentifier(z)) - /// // Prints "false" - /// print(x === z) - /// // Prints "false" - /// - /// - Parameter x: An instance of a class. - public init(_ x: AnyObject) { - self._value = Builtin.bridgeToRawPointer(x) - } - - /// Creates an instance that uniquely identifies the given metatype. - /// - /// - Parameter: A metatype. - public init(_ x: Any.Type) { - self._value = unsafeBitCast(x, to: Builtin.RawPointer.self) - } -} - -extension ObjectIdentifier : CustomDebugStringConvertible { - /// A textual representation of the identifier, suitable for debugging. - public var debugDescription: String { - return "ObjectIdentifier(\(_rawPointerToString(_value)))" - } -} - -extension ObjectIdentifier : Comparable { - public static func < (lhs: ObjectIdentifier, rhs: ObjectIdentifier) -> Bool { - return UInt(bitPattern: lhs) < UInt(bitPattern: rhs) - } - - public static func == (x: ObjectIdentifier, y: ObjectIdentifier) -> Bool { - return Bool(Builtin.cmp_eq_RawPointer(x._value, y._value)) - } -} - -extension UInt { - /// Creates an integer that captures the full value of the given object - /// identifier. - public init(bitPattern objectID: ObjectIdentifier) { - self.init(Builtin.ptrtoint_Word(objectID._value)) - } -} - -extension Int { - /// Creates an integer that captures the full value of the given object - /// identifier. - public init(bitPattern objectID: ObjectIdentifier) { - self.init(bitPattern: UInt(bitPattern: objectID)) - } -} - /// How children of this value should be presented in the IDE. public enum _MirrorDisposition { /// As a struct. @@ -171,213 +79,6 @@ func _getSummary(_ out: UnsafeMutablePointer, x: T) { @_silgen_name("swift_reflectAny") internal func _reflect(_ x: T) -> _Mirror -/// 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) - } -} - // -- Implementation details for the runtime's _Mirror implementation @_silgen_name("swift_MagicMirrorData_summary") @@ -657,23 +358,3 @@ struct _MetatypeMirror : _Mirror { var disposition: _MirrorDisposition { return .aggregate } } -extension ObjectIdentifier { - @available(*, unavailable, message: "use the 'UInt(_:)' initializer") - public var uintValue: UInt { - Builtin.unreachable() - } -} - -extension UInt { - @available(*, unavailable, renamed: "init(bitPattern:)") - public init(_ objectID: ObjectIdentifier) { - Builtin.unreachable() - } -} - -extension Int { - @available(*, unavailable, renamed: "init(bitPattern:)") - public init(_ objectID: ObjectIdentifier) { - Builtin.unreachable() - } -} From cee0d7a3346ae531c7a7f0631ccfbe1113e6d3b1 Mon Sep 17 00:00:00 2001 From: Dmitri Gribenko Date: Sat, 3 Sep 2016 17:49:52 -0700 Subject: [PATCH 2/2] stdlib: rename Reflection.swift to ReflectionLegacy.swift --- stdlib/public/core/CMakeLists.txt | 2 +- stdlib/public/core/GroupInfo.json | 2 +- stdlib/public/core/{Reflection.swift => ReflectionLegacy.swift} | 0 3 files changed, 2 insertions(+), 2 deletions(-) rename stdlib/public/core/{Reflection.swift => ReflectionLegacy.swift} (100%) diff --git a/stdlib/public/core/CMakeLists.txt b/stdlib/public/core/CMakeLists.txt index 17df73825e86c..4de4be96f0ddc 100644 --- a/stdlib/public/core/CMakeLists.txt +++ b/stdlib/public/core/CMakeLists.txt @@ -96,7 +96,7 @@ set(SWIFTLIB_ESSENTIAL RandomAccessCollection.swift Range.swift.gyb RangeReplaceableCollection.swift.gyb - Reflection.swift + ReflectionLegacy.swift Repeat.swift REPL.swift Reverse.swift diff --git a/stdlib/public/core/GroupInfo.json b/stdlib/public/core/GroupInfo.json index 207153b32b92b..5cbba05b57764 100644 --- a/stdlib/public/core/GroupInfo.json +++ b/stdlib/public/core/GroupInfo.json @@ -100,7 +100,7 @@ "Mirrors.swift", "ObjCMirrors.swift", "ObjectIdentifier.swift", - "Reflection.swift" + "ReflectionLegacy.swift" ], "Math": [ "SetAlgebra.swift", diff --git a/stdlib/public/core/Reflection.swift b/stdlib/public/core/ReflectionLegacy.swift similarity index 100% rename from stdlib/public/core/Reflection.swift rename to stdlib/public/core/ReflectionLegacy.swift