Skip to content

[5.4] Revert lazy children improvement in Swift Mirror #35393

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion stdlib/public/core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@ set(SWIFTLIB_ESSENTIAL
DictionaryVariant.swift
DropWhile.swift
Dump.swift
EitherSequence.swift
EmptyCollection.swift
Equatable.swift
ErrorType.swift
Expand Down
8 changes: 4 additions & 4 deletions stdlib/public/core/DebuggerSupport.swift
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ public enum _DebuggerSupport {

private static func ivarCount(mirror: Mirror) -> Int {
let ivars = mirror.superclassMirror.map(ivarCount) ?? 0
return ivars + mirror._children.count
return ivars + mirror.children.count
}

private static func shouldExpand(
Expand All @@ -119,7 +119,7 @@ public enum _DebuggerSupport {
isRoot: Bool
) -> Bool {
if isRoot || collectionStatus.isCollection { return true }
if !mirror._children.isEmpty { return true }
if !mirror.children.isEmpty { return true }
if mirror.displayStyle == .`class` { return true }
if let sc = mirror.superclassMirror { return ivarCount(mirror: sc) > 0 }
return true
Expand Down Expand Up @@ -161,7 +161,7 @@ public enum _DebuggerSupport {
}
let willExpand = isNonClass || isCustomReflectable

let count = mirror._children.count
let count = mirror.children.count
let bullet = isRoot && (count == 0 || !willExpand) ? ""
: count == 0 ? "- "
: maxDepth <= 0 ? "▹ " : "▿ "
Expand Down Expand Up @@ -209,7 +209,7 @@ public enum _DebuggerSupport {
target: &target)
}

for (optionalName,child) in mirror._children {
for (optionalName,child) in mirror.children {
let childName = optionalName ?? "\(printedElements)"
if maxItemCounter <= 0 {
print(String(repeating: " ", count: indent+4), terminator: "", to: &target)
Expand Down
16 changes: 8 additions & 8 deletions stdlib/public/core/Dump.swift
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ internal func _dump_unlocked<TargetStream: TextOutputStream>(
for _ in 0..<indent { target.write(" ") }

let mirror = Mirror(reflecting: value)
let count = mirror._children.count
let count = mirror.children.count
let bullet = count == 0 ? "-"
: maxDepth <= 0 ? "▹" : "▿"
target.write(bullet)
Expand Down Expand Up @@ -149,7 +149,7 @@ internal func _dump_unlocked<TargetStream: TextOutputStream>(
visitedItems: &visitedItems)
}

var currentIndex = mirror._children.startIndex
var currentIndex = mirror.children.startIndex
for i in 0..<count {
if maxItemCounter <= 0 {
for _ in 0..<(indent+4) {
Expand All @@ -167,8 +167,8 @@ internal func _dump_unlocked<TargetStream: TextOutputStream>(
return
}

let (name, child) = mirror._children[currentIndex]
mirror._children.formIndex(after: &currentIndex)
let (name, child) = mirror.children[currentIndex]
mirror.children.formIndex(after: &currentIndex)
_dump_unlocked(
child,
to: &target,
Expand Down Expand Up @@ -196,7 +196,7 @@ internal func _dumpSuperclass_unlocked<TargetStream: TextOutputStream>(

for _ in 0..<indent { target.write(" ") }

let count = mirror._children.count
let count = mirror.children.count
let bullet = count == 0 ? "-"
: maxDepth <= 0 ? "▹" : "▿"
target.write(bullet)
Expand All @@ -216,7 +216,7 @@ internal func _dumpSuperclass_unlocked<TargetStream: TextOutputStream>(
visitedItems: &visitedItems)
}

var currentIndex = mirror._children.startIndex
var currentIndex = mirror.children.startIndex
for i in 0..<count {
if maxItemCounter <= 0 {
for _ in 0..<(indent+4) {
Expand All @@ -234,8 +234,8 @@ internal func _dumpSuperclass_unlocked<TargetStream: TextOutputStream>(
return
}

let (name, child) = mirror._children[currentIndex]
mirror._children.formIndex(after: &currentIndex)
let (name, child) = mirror.children[currentIndex]
mirror.children.formIndex(after: &currentIndex)
_dump_unlocked(
child,
to: &target,
Expand Down
1 change: 0 additions & 1 deletion stdlib/public/core/GroupInfo.json
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,6 @@
"RandomAccessCollection.swift",
"MutableCollection.swift",
"CollectionAlgorithms.swift",
"EitherSequence.swift",
"EmptyCollection.swift",
"Stride.swift",
"Repeat.swift",
Expand Down
126 changes: 62 additions & 64 deletions stdlib/public/core/Mirror.swift
Original file line number Diff line number Diff line change
Expand Up @@ -100,13 +100,25 @@ public struct Mirror {
/// `superclassMirror` property is `nil`.
case suppressed
}


/// The static type of the subject being reflected.
/// Creates a mirror that reflects on the given instance.
///
/// This type may differ from the subject's dynamic type when this mirror
/// is the `superclassMirror` of another mirror.
public let subjectType: Any.Type
/// 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.
///
/// If the dynamic type of `subject` has value semantics, subsequent
/// mutations of `subject` will not observable in `Mirror`. In general,
/// though, the observability of mutations is unspecified.
///
/// - Parameter subject: The instance for which to create a mirror.
public init(reflecting subject: Any) {
if case let customized as CustomReflectable = subject {
self = customized.customMirror
} else {
self = Mirror(internalReflecting: subject)
}
}

/// An element of the reflected instance's structure.
///
Expand All @@ -130,26 +142,6 @@ public struct Mirror {
/// }
public typealias Children = AnyCollection<Child>

internal typealias _Children
= _EitherCollection<ReflectedChildren,AnyCollection<Child>>

internal var _children: _Children

/// A collection of `Child` elements describing the structure of the
/// reflected subject.
public var children: Children { AnyCollection(_children) }

/// A suggested display style for the reflected subject.
public let displayStyle: DisplayStyle?

/// A mirror of the subject's superclass, if one exists.
public var superclassMirror: Mirror? {
return _makeSuperclassMirror()
}

internal let _makeSuperclassMirror: () -> Mirror?
internal let _defaultDescendantRepresentation: _DefaultDescendantRepresentation

/// A suggestion of how a mirror's subject is to be interpreted.
///
/// Playgrounds and the debugger will show a representation similar
Expand All @@ -160,25 +152,6 @@ public struct Mirror {
case dictionary, `set`
}

/// Creates a mirror that reflects on the given instance.
///
/// 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.
///
/// If the dynamic type of `subject` has value semantics, subsequent
/// mutations of `subject` will not observable in `Mirror`. In general,
/// though, the observability of mutations is unspecified.
///
/// - Parameter subject: The instance for which to create a mirror.
public init(reflecting subject: Any) {
if case let customized as CustomReflectable = subject {
self = customized.customMirror
} else {
self = Mirror(internalReflecting: subject)
}
}

internal static func _noSuperclassMirror() -> Mirror? { return nil }

@_semantics("optimize.sil.specialize.generic.never")
Expand Down Expand Up @@ -250,7 +223,7 @@ public struct Mirror {
self._makeSuperclassMirror = Mirror._superclassIterator(
subject, ancestorRepresentation)

self._children = _Children(children)
self.children = Children(children)
self.displayStyle = displayStyle
self._defaultDescendantRepresentation
= subject is CustomLeafReflectable ? .suppressed : .generated
Expand Down Expand Up @@ -295,7 +268,7 @@ public struct Mirror {

let lazyChildren =
unlabeledChildren.lazy.map { Child(label: nil, value: $0) }
self._children = _Children(lazyChildren)
self.children = Children(lazyChildren)

self.displayStyle = displayStyle
self._defaultDescendantRepresentation
Expand Down Expand Up @@ -342,12 +315,33 @@ public struct Mirror {
subject, ancestorRepresentation)

let lazyChildren = children.lazy.map { Child(label: $0.0, value: $0.1) }
self._children = _Children(lazyChildren)
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 this mirror
/// 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

/// A suggested display style for the reflected subject.
public let displayStyle: DisplayStyle?

/// A mirror of the subject's superclass, if one exists.
public var superclassMirror: Mirror? {
return _makeSuperclassMirror()
}

internal let _makeSuperclassMirror: () -> Mirror?
internal let _defaultDescendantRepresentation: _DefaultDescendantRepresentation
}

/// A type that explicitly supplies its own mirror.
Expand Down Expand Up @@ -384,6 +378,14 @@ extension Int: MirrorPath {}
extension String: MirrorPath {}

extension Mirror {
internal struct _Dummy: CustomReflectable {
internal init(mirror: Mirror) {
self.mirror = mirror
}
internal var mirror: Mirror
internal var customMirror: Mirror { return mirror }
}

/// Returns a specific descendant of the reflected subject, or `nil` if no
/// such descendant exists.
///
Expand Down Expand Up @@ -431,28 +433,24 @@ extension Mirror {
public func descendant(
_ first: MirrorPath, _ rest: MirrorPath...
) -> Any? {

func fetch(_ path: MirrorPath, in children: _Children) -> Any? {
let position: _Children.Index?
switch path {
case let label as String:
position = children.firstIndex { $0.label == label }
case let offset as Int:
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.firstIndex { $0.label == label } ?? children.endIndex
}
else if let offset = e as? Int {
position = children.index(children.startIndex,
offsetBy: offset,
limitedBy: children.endIndex)
default:
limitedBy: children.endIndex) ?? children.endIndex
}
else {
_preconditionFailure(
"Someone added a conformance to MirrorPath; that privilege is reserved to the standard library")
}
return position.map { children[$0].value }
}

guard var result = fetch(first, in: _children) else { return nil }
for path in rest {
guard let next = fetch(path, in: Mirror(reflecting: result)._children)
else { return nil }
result = next
if position == children.endIndex { return nil }
result = children[position].value
}
return result
}
Expand Down
16 changes: 8 additions & 8 deletions stdlib/public/core/OutputStream.swift
Original file line number Diff line number Diff line change
Expand Up @@ -290,15 +290,15 @@ internal func _adHocPrint_unlocked<T, TargetStream: TextOutputStream>(
if let displayStyle = mirror.displayStyle {
switch displayStyle {
case .optional:
if let child = mirror._children.first {
if let child = mirror.children.first {
_debugPrint_unlocked(child.1, &target)
} else {
_debugPrint_unlocked("nil", &target)
}
case .tuple:
target.write("(")
var first = true
for (label, value) in mirror._children {
for (label, value) in mirror.children {
if first {
first = false
} else {
Expand All @@ -319,7 +319,7 @@ internal func _adHocPrint_unlocked<T, TargetStream: TextOutputStream>(
printTypeName(mirror.subjectType)
target.write("(")
var first = true
for (label, value) in mirror._children {
for (label, value) in mirror.children {
if let label = label {
if first {
first = false
Expand All @@ -345,7 +345,7 @@ internal func _adHocPrint_unlocked<T, TargetStream: TextOutputStream>(
// If the case name is garbage, just print the type name.
printTypeName(mirror.subjectType)
}
if let (_, value) = mirror._children.first {
if let (_, value) = mirror.children.first {
if Mirror(reflecting: value).displayStyle == .tuple {
_debugPrint_unlocked(value, &target)
} else {
Expand Down Expand Up @@ -450,19 +450,19 @@ internal func _dumpPrint_unlocked<T, TargetStream: TextOutputStream>(
// count
switch displayStyle {
case .tuple:
let count = mirror._children.count
let count = mirror.children.count
target.write(count == 1 ? "(1 element)" : "(\(count) elements)")
return
case .collection:
let count = mirror._children.count
let count = mirror.children.count
target.write(count == 1 ? "1 element" : "\(count) elements")
return
case .dictionary:
let count = mirror._children.count
let count = mirror.children.count
target.write(count == 1 ? "1 key/value pair" : "\(count) key/value pairs")
return
case .`set`:
let count = mirror._children.count
let count = mirror.children.count
target.write(count == 1 ? "1 member" : "\(count) members")
return
default:
Expand Down
26 changes: 9 additions & 17 deletions stdlib/public/core/ReflectionMirror.swift
Original file line number Diff line number Diff line change
Expand Up @@ -128,25 +128,17 @@ internal func _getClassPlaygroundQuickLook(
#endif

extension Mirror {
internal struct ReflectedChildren: RandomAccessCollection {
let subject: Any
let subjectType: Any.Type
var startIndex: Int { 0 }
var endIndex: Int { _getChildCount(subject, type: subjectType) }
subscript(index: Int) -> Child {
getChild(of: subject, type: subjectType, index: index)
}
}

internal init(
internalReflecting subject: Any,
subjectType: Any.Type? = nil,
customAncestor: Mirror? = nil
) {
internal init(internalReflecting subject: Any,
subjectType: Any.Type? = nil,
customAncestor: Mirror? = nil)
{
let subjectType = subjectType ?? _getNormalizedType(subject, type: type(of: subject))

self._children = _Children(
ReflectedChildren(subject: subject, subjectType: subjectType))
let childCount = _getChildCount(subject, type: subjectType)
let children = (0 ..< childCount).lazy.map({
getChild(of: subject, type: subjectType, index: $0)
})
self.children = Children(children)

self._makeSuperclassMirror = {
guard let subjectClass = subjectType as? AnyClass,
Expand Down