Files
swift-mirror/test/stdlib/Mirror.swift
Joe Groff b51d43377e Runtime: Properly handle demangling nested generic typerefs with symbolic manglings.
The demangling tree for a symbolic reference doesn't indicate the generic context depth of the referenced type, so we have to form the type metadata from whole cloth without incrementally building up nested types as we do for concrete mangled types. Notice when DecodedMetadataBuilder is passed a context descriptor ref without a parent and directly form the entire type in this case. Fixes rdar://problem/38891999.
2018-04-05 16:23:16 -07:00

802 lines
22 KiB
Swift

//===--- 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
//
//===----------------------------------------------------------------------===//
// RUN: %empty-directory(%t)
//
// RUN: if [ %target-runtime == "objc" ]; \
// RUN: then \
// RUN: %target-clang %S/Inputs/Mirror/Mirror.mm -c -o %t/Mirror.mm.o -g && \
// RUN: %target-build-swift %s -I %S/Inputs/Mirror/ -Xlinker %t/Mirror.mm.o -o %t/Mirror; \
// RUN: else \
// RUN: %target-build-swift %s -o %t/Mirror; \
// RUN: fi
// RUN: %target-run %t/Mirror
// REQUIRES: executable_test
import StdlibUnittest
var mirrors = TestSuite("Mirrors")
extension Mirror {
public var testDescription: String {
let nil_ = "nil"
return "[" +
children.lazy
.map { "\($0.0 ?? nil_): \(String(reflecting: $0.1))" }
.joined(separator: ", ")
+ "]"
}
}
mirrors.test("RandomAccessStructure") {
struct Eggs : CustomReflectable {
var customMirror: Mirror {
return Mirror(self, unlabeledChildren: ["aay", "bee", "cee"])
}
}
let x = Eggs().customMirror
expectEqual("[nil: \"aay\", nil: \"bee\", nil: \"cee\"]", x.testDescription)
}
let letters = "abcdefghijklmnopqrstuvwxyz "
func find(_ substring: String, within domain: String) -> String.Index? {
let domainCount = domain.count
let substringCount = substring.count
if (domainCount < substringCount) { return nil }
var sliceStart = domain.startIndex
var sliceEnd = domain.index(sliceStart, offsetBy: substringCount)
var i = 0
while true {
if domain[sliceStart..<sliceEnd] == substring {
return sliceStart
}
if i == domainCount - substringCount { break }
sliceStart = domain.index(after: sliceStart)
sliceEnd = domain.index(after: sliceEnd)
i += 1
}
return nil
}
mirrors.test("ForwardStructure") {
struct DoubleYou : CustomReflectable {
var customMirror: Mirror {
return Mirror(
self,
unlabeledChildren: Set(letters),
displayStyle: .`set`)
}
}
let w = DoubleYou().customMirror
expectEqual(.`set`, w.displayStyle)
expectEqual(letters.count, numericCast(w.children.count))
// Because we don't control the order of a Set, we need to do a
// fancy dance in order to validate the result.
let description = w.testDescription
for c in letters {
let expected = "nil: \"\(c)\""
expectNotNil(find(expected, within: description))
}
}
mirrors.test("BidirectionalStructure") {
struct Why : CustomReflectable {
var customMirror: Mirror {
return Mirror(
self,
unlabeledChildren: letters,
displayStyle: .collection)
}
}
// Test that the basics seem to work
let y = Why().customMirror
expectEqual(.`collection`, y.displayStyle)
let description = y.testDescription
expectEqual(
"[nil: \"a\", nil: \"b\", nil: \"c\", nil: \"",
description[description.startIndex..<description.index(of: "d")!])
}
mirrors.test("LabeledStructure") {
struct Zee : CustomReflectable, CustomStringConvertible {
var customMirror: Mirror {
return Mirror(self, children: ["bark": 1, "bite": 0])
}
var description: String { return "Zee" }
}
let z = Zee().customMirror
expectEqual("[bark: 1, bite: 0]", z.testDescription)
expectNil(z.displayStyle)
struct Zee2 : CustomReflectable {
var customMirror: Mirror {
return Mirror(
self, children: ["bark": 1, "bite": 0], displayStyle: .dictionary)
}
}
let z2 = Zee2().customMirror
expectEqual(.dictionary, z2.displayStyle)
expectEqual("[bark: 1, bite: 0]", z2.testDescription)
struct Heterogeny : CustomReflectable {
var customMirror: Mirror {
return Mirror(
self, children: ["bark": 1, "bite": Zee()])
}
}
let h = Heterogeny().customMirror
expectEqual("[bark: 1, bite: Zee]", h.testDescription)
}
mirrors.test("Legacy") {
let m = Mirror(reflecting: [1, 2, 3])
expectTrue(m.subjectType == [Int].self)
let x0: [Mirror.Child] = [
(label: nil, value: 1),
(label: nil, value: 2),
(label: nil, value: 3)
]
expectFalse(
zip(x0, m.children).contains {
$0.0.value as! Int != $0.1.value as! Int
})
class B { let bx: Int = 0 }
class D : B { let dx: Int = 1 }
let mb = Mirror(reflecting: B())
func expectBMirror(
_ mb: Mirror, stackTrace: SourceLocStack = SourceLocStack(),
file: String = #file, line: UInt = #line
) {
expectTrue(mb.subjectType == B.self,
stackTrace: stackTrace, file: file, line: line)
expectNil(
mb.superclassMirror,
stackTrace: stackTrace, file: file, line: line)
expectEqual(
1, mb.children.count,
stackTrace: stackTrace, file: file, line: line)
expectEqual(
"bx", mb.children.first?.label,
stackTrace: stackTrace, file: file, line: line)
expectEqual(
0, mb.children.first?.value as? Int,
stackTrace: stackTrace, file: file, line: line)
}
expectBMirror(mb)
// Ensure that the base class instance is properly filtered out of
// the child list
do {
let md = Mirror(reflecting: D())
expectTrue(md.subjectType == D.self)
expectEqual(1, md.children.count)
expectEqual("dx", md.children.first?.label)
expectEqual(1, md.children.first?.value as? Int)
expectNotNil(md.superclassMirror)
if let mb2 = md.superclassMirror { expectBMirror(mb2) }
}
do {
// Ensure that we reflect on the dynamic type of the subject
let md = Mirror(reflecting: D() as B)
expectTrue(md.subjectType == D.self)
expectEqual(1, md.children.count)
expectEqual("dx", md.children.first?.label)
expectEqual(1, md.children.first?.value as? Int)
expectNotNil(md.superclassMirror)
if let mb2 = md.superclassMirror { expectBMirror(mb2) }
}
}
//===----------------------------------------------------------------------===//
//===--- Class Support ----------------------------------------------------===//
mirrors.test("Class/Root/Uncustomized") {
class A { var a: Int = 1 }
let a = Mirror(reflecting: A())
expectTrue(a.subjectType == A.self)
expectNil(a.superclassMirror)
expectEqual(1, a.children.count)
expectEqual("a", a.children.first!.label)
}
//===--- Generated Superclass Mirrors -------------------------------------===//
mirrors.test("Class/Root/superclass:.generated") {
class B : CustomReflectable {
var b: String = "two"
var customMirror: Mirror {
return Mirror(
self, children: ["bee": b], ancestorRepresentation: .generated)
}
}
let b = Mirror(reflecting: B())
expectTrue(b.subjectType == B.self)
expectNil(b.superclassMirror)
expectEqual(1, b.children.count)
expectEqual("bee", b.children.first!.label)
expectEqual("two", b.children.first!.value as? String)
}
mirrors.test("class/Root/superclass:<default>") {
class C : CustomReflectable {
var c: UInt = 3
var customMirror: Mirror {
return Mirror(self, children: ["sea": c + 1])
}
}
let c = Mirror(reflecting: C())
expectTrue(c.subjectType == C.self)
expectNil(c.superclassMirror)
expectEqual(1, c.children.count)
expectEqual("sea", c.children.first!.label)
expectEqual(4, c.children.first!.value as? UInt)
}
mirrors.test("class/Plain/Plain") {
class A { var a: Int = 1 }
class B : A { var b: UInt = 42 }
let b = Mirror(reflecting: B())
expectTrue(b.subjectType == B.self)
if let bChild = expectNotNil(b.children.first) {
expectEqual("b", bChild.label)
expectEqual(42, bChild.value as? UInt)
}
if let a = expectNotNil(b.superclassMirror) {
expectTrue(a.subjectType == A.self)
if let aChild = expectNotNil(a.children.first) {
expectEqual("a", aChild.label)
expectEqual(1, aChild.value as? Int)
expectNil(a.superclassMirror)
}
}
}
mirrors.test("class/UncustomizedSuper/Synthesized/Implicit") {
class A { var a: Int = 1 }
class B : A, CustomReflectable {
var b: UInt = 42
var customMirror: Mirror {
return Mirror(self, children: ["bee": b])
}
}
let b = Mirror(reflecting: B())
expectTrue(b.subjectType == B.self)
if let a = expectNotNil(b.superclassMirror) {
expectTrue(a.subjectType == A.self)
expectEqual("a", a.children.first?.label)
expectNil(a.superclassMirror)
}
}
mirrors.test("class/UncustomizedSuper/Synthesized/Explicit") {
class A { var a: Int = 1 }
class B : A, CustomReflectable {
var b: UInt = 42
var customMirror: Mirror {
return Mirror(
self, children: ["bee": b], ancestorRepresentation: .generated)
}
}
let b = Mirror(reflecting: B())
expectTrue(b.subjectType == B.self)
if let a = expectNotNil(b.superclassMirror) {
expectTrue(a.subjectType == A.self)
expectEqual("a", a.children.first!.label)
expectNil(a.superclassMirror)
}
}
mirrors.test("class/CustomizedSuper/Synthesized") {
class A : CustomReflectable {
var a: Int = 1
var customMirror: Mirror {
return Mirror(self, children: ["aye": a])
}
}
class B : A {
var b: UInt = 42
// This is an unusual case: when writing override on a
// customMirror implementation you would typically want to pass
// ancestorRepresentation: .customized(super.customMirror) or, in
// rare cases, ancestorRepresentation: .Suppressed. However, it
// has an expected behavior, which we test here.
override var customMirror: Mirror {
return Mirror(self, children: ["bee": b])
}
}
let b = Mirror(reflecting: B())
expectTrue(b.subjectType == B.self)
if let a = expectNotNil(b.superclassMirror) {
expectTrue(a.subjectType == A.self)
expectEqual("a", a.children.first!.label)
expectNil(a.superclassMirror)
}
}
#if _runtime(_ObjC)
import Foundation
//===--- ObjC Base Classes ------------------------------------------------===//
mirrors.test("class/ObjCPlain/Plain") {
class A : NSObject { var a: Int = 1 }
class B : A { var b: UInt = 42 }
let b = Mirror(reflecting: B())
expectTrue(b.subjectType == B.self)
if let bChild = expectNotNil(b.children.first) {
expectEqual("b", bChild.label)
expectEqual(42, bChild.value as? UInt)
}
if let a = expectNotNil(b.superclassMirror) {
expectTrue(a.subjectType == A.self)
if let aChild = expectNotNil(a.children.first) {
expectEqual("a", aChild.label)
expectEqual(1, aChild.value as? Int)
if let o = expectNotNil(a.superclassMirror) {
expectEqual("NSObject", String(reflecting: o.subjectType))
}
}
}
}
mirrors.test("class/ObjCUncustomizedSuper/Synthesized/Implicit") {
class A : NSObject { var a: Int = 1 }
class B : A, CustomReflectable {
var b: UInt = 42
var customMirror: Mirror {
return Mirror(self, children: ["bee": b])
}
}
let b = Mirror(reflecting: B())
expectTrue(b.subjectType == B.self)
if let a = expectNotNil(b.superclassMirror) {
expectTrue(a.subjectType == A.self)
expectEqual("a", a.children.first?.label)
if let o = expectNotNil(a.superclassMirror) {
expectTrue(o.subjectType == NSObject.self)
}
}
}
mirrors.test("class/ObjCUncustomizedSuper/Synthesized/Explicit") {
class A : NSObject { var a: Int = 1 }
class B : A, CustomReflectable {
var b: UInt = 42
var customMirror: Mirror {
return Mirror(
self, children: ["bee": b], ancestorRepresentation: .generated)
}
}
let b = Mirror(reflecting: B())
expectTrue(b.subjectType == B.self)
if let a = expectNotNil(b.superclassMirror) {
expectTrue(a.subjectType == A.self)
expectEqual("a", a.children.first!.label)
if let o = expectNotNil(a.superclassMirror) {
expectTrue(o.subjectType == NSObject.self)
}
}
}
mirrors.test("class/ObjCCustomizedSuper/Synthesized") {
class A : DateFormatter, CustomReflectable {
var a: Int = 1
var customMirror: Mirror {
return Mirror(self, children: ["aye": a])
}
}
class B : A {
var b: UInt = 42
// This is an unusual case: when writing override on a
// customMirror implementation you would typically want to pass
// ancestorRepresentation: .customized(super.customMirror) or, in
// rare cases, ancestorRepresentation: .Suppressed. However, it
// has an expected behavior, which we test here.
override var customMirror: Mirror {
return Mirror(self, children: ["bee": b])
}
}
let b = Mirror(reflecting: B())
expectTrue(b.subjectType == B.self)
if let a = expectNotNil(b.superclassMirror) {
expectTrue(a.subjectType == A.self)
expectEqual("a", a.children.first!.label)
if let d = expectNotNil(a.superclassMirror) {
expectTrue(d.subjectType == DateFormatter.self)
if let f = expectNotNil(d.superclassMirror) {
expectTrue(f.subjectType == Formatter.self)
if let o = expectNotNil(f.superclassMirror) {
expectTrue(o.subjectType == NSObject.self)
expectNil(o.superclassMirror)
}
}
}
}
}
#endif // _runtime(_ObjC)
//===--- Suppressed Superclass Mirrors ------------------------------------===//
mirrors.test("Class/Root/NoSuperclassMirror") {
class B : CustomReflectable {
var b: String = "two"
var customMirror: Mirror {
return Mirror(
self, children: ["bee": b], ancestorRepresentation: .suppressed)
}
}
let b = Mirror(reflecting: B())
expectTrue(b.subjectType == B.self)
expectNil(b.superclassMirror)
expectEqual(1, b.children.count)
expectEqual("bee", b.children.first!.label)
}
mirrors.test("class/UncustomizedSuper/NoSuperclassMirror") {
class A { var a: Int = 1 }
class B : A, CustomReflectable {
var b: UInt = 42
var customMirror: Mirror {
return Mirror(
self, children: ["bee": b], ancestorRepresentation: .suppressed)
}
}
let b = Mirror(reflecting: B())
expectTrue(b.subjectType == B.self)
expectNil(b.superclassMirror)
}
mirrors.test("class/CustomizedSuper/NoSuperclassMirror") {
class A : CustomReflectable {
var a: Int = 1
var customMirror: Mirror {
return Mirror(self, children: ["aye": a])
}
}
class B : A {
var b: UInt = 42
override var customMirror: Mirror {
return Mirror(
self, children: ["bee": b], ancestorRepresentation: .suppressed)
}
}
let b = Mirror(reflecting: B())
expectTrue(b.subjectType == B.self)
expectNil(b.superclassMirror)
}
//===--- Override Superclass Mirrors --------------------------------------===//
mirrors.test("class/CustomizedSuper/SuperclassCustomMirror/Direct") {
class A : CustomReflectable {
var a: Int = 1
var customMirror: Mirror {
return Mirror(self, children: ["aye": a])
}
}
// B inherits A directly
class B : A {
var b: UInt = 42
override var customMirror: Mirror {
return Mirror(
self,
children: ["bee": b],
ancestorRepresentation: .customized({ super.customMirror }))
}
}
let b = Mirror(reflecting: B())
expectTrue(b.subjectType == B.self)
if let a = expectNotNil(b.superclassMirror) {
expectTrue(a.subjectType == A.self)
expectEqual("aye", a.children.first!.label)
expectNil(a.superclassMirror)
}
}
mirrors.test("class/CustomizedSuper/SuperclassCustomMirror/Indirect") {
class A : CustomReflectable {
var a: Int = 1
var customMirror: Mirror {
return Mirror(self, children: ["aye": a])
}
}
class X : A {}
class Y : X {}
// B inherits A indirectly through X and Y
class B : Y {
var b: UInt = 42
override var customMirror: Mirror {
return Mirror(
self,
children: ["bee": b],
ancestorRepresentation: .customized({ super.customMirror }))
}
}
let b = Mirror(reflecting: B())
expectTrue(b.subjectType == B.self)
if let y = expectNotNil(b.superclassMirror) {
expectTrue(y.subjectType == Y.self)
if let x = expectNotNil(y.superclassMirror) {
expectTrue(x.subjectType == X.self)
expectEqual(0, x.children.count)
if let a = expectNotNil(x.superclassMirror) {
expectTrue(a.subjectType == A.self)
if let aye = expectNotNil(a.children.first) {
expectEqual("aye", aye.label)
}
}
}
}
}
mirrors.test("class/CustomizedSuper/SuperclassCustomMirror/Indirect2") {
class A : CustomLeafReflectable {
var a: Int = 1
var customMirror: Mirror {
return Mirror(
self, children: ["aye": a])
}
}
class X : A {}
class Y : X {}
// B inherits A indirectly through X and Y
class B : Y {
var b: UInt = 42
override var customMirror: Mirror {
return Mirror(
self,
children: ["bee": b],
ancestorRepresentation: .customized({ super.customMirror }))
}
}
let b = Mirror(reflecting: B())
expectTrue(b.subjectType == B.self)
if let a = expectNotNil(b.superclassMirror) {
expectTrue(a.subjectType == A.self)
if let aye = expectNotNil(a.children.first) {
expectEqual("aye", aye.label)
}
}
}
mirrors.test("class/Cluster") {
class A : CustomLeafReflectable {
var a: Int = 1
var customMirror: Mirror {
return Mirror(
self, children: ["aye": a])
}
}
class X : A {}
class Y : X {}
let a = Mirror(reflecting: Y())
expectTrue(a.subjectType == A.self)
if let aye = expectNotNil(a.children.first) {
expectEqual("aye", aye.label)
}
}
//===--- End Class Support ------------------------------------------------===//
//===----------------------------------------------------------------------===//
mirrors.test("Addressing") {
let m0 = Mirror(reflecting: [1, 2, 3])
expectEqual(1, m0.descendant(0) as? Int)
expectEqual(2, m0.descendant(1) as? Int)
expectEqual(3, m0.descendant(2) as? Int)
let m1 = Mirror(reflecting: (a: ["one", "two", "three"], 4))
let ott0 = m1.descendant(0) as? [String]
expectNotNil(ott0)
let ott1 = m1.descendant("a") as? [String]
expectNotNil(ott1)
if ott0 != nil && ott1 != nil {
expectEqualSequence(ott0!, ott1!)
}
expectEqual(4, m1.descendant(1) as? Int)
expectEqual(4, m1.descendant(".1") as? Int)
expectEqual("one", m1.descendant(0, 0) as? String)
expectEqual("two", m1.descendant(0, 1) as? String)
expectEqual("three", m1.descendant(0, 2) as? String)
expectEqual("one", m1.descendant("a", 0) as? String)
struct Zee : CustomReflectable {
var customMirror: Mirror {
return Mirror(self, children: ["bark": 1, "bite": 0])
}
}
let x = [
(a: ["one", "two", "three"], b: Zee()),
(a: ["five"], b: Zee()),
(a: [], b: Zee())]
let m = Mirror(reflecting: x)
let two = m.descendant(0, "a", 1)
expectEqual("two", two as? String)
expectEqual(1, m.descendant(1, 1, "bark") as? Int)
expectEqual(0, m.descendant(1, 1, "bite") as? Int)
expectNil(m.descendant(1, 1, "bork"))
}
mirrors.test("Invalid Path Type")
.skip(.custom(
{ _isFastAssertConfiguration() },
reason: "this trap is not guaranteed to happen in -Ounchecked"))
.code {
struct X : MirrorPath {}
let m = Mirror(reflecting: [1, 2, 3])
expectEqual(1, m.descendant(0) as? Int)
expectCrashLater()
_ = m.descendant(X())
}
mirrors.test("PlaygroundQuickLook") {
// Customization works.
struct CustomQuickie : CustomPlaygroundQuickLookable {
var customPlaygroundQuickLook: PlaygroundQuickLook {
return .point(1.25, 42)
}
}
switch PlaygroundQuickLook(reflecting: CustomQuickie()) {
case .point(1.25, 42): break
default: expectTrue(false)
}
// PlaygroundQuickLook support from Legacy Mirrors works.
switch PlaygroundQuickLook(reflecting: true) {
case .bool(true): break
default: expectTrue(false)
}
// With no Legacy Mirror QuickLook support, we fall back to
// String(reflecting: ).
struct X {}
switch PlaygroundQuickLook(reflecting: X()) {
case .text(let text):
#if _runtime(_ObjC)
// FIXME: Enable if non-objc hasSuffix is implemented.
expectTrue(text.contains(").X"), text)
#endif
default:
expectTrue(false)
}
struct Y : CustomDebugStringConvertible {
var debugDescription: String { return "Why?" }
}
switch PlaygroundQuickLook(reflecting: Y()) {
case .text("Why?"): break
default: expectTrue(false)
}
}
class Parent {}
extension Parent : _DefaultCustomPlaygroundQuickLookable {
var _defaultCustomPlaygroundQuickLook: PlaygroundQuickLook {
return .text("base")
}
}
class Child : Parent { }
class FancyChild : Parent, CustomPlaygroundQuickLookable {
var customPlaygroundQuickLook: PlaygroundQuickLook {
return .text("child")
}
}
mirrors.test("_DefaultCustomPlaygroundQuickLookable") {
// testing the workaround for custom quicklookables in subclasses
switch PlaygroundQuickLook(reflecting: Child()) {
case .text("base"): break
default: expectUnreachable("Base custom quicklookable was expected")
}
switch PlaygroundQuickLook(reflecting: FancyChild()) {
case .text("child"): break
default: expectUnreachable("FancyChild custom quicklookable was expected")
}
}
#if _runtime(_ObjC)
import MirrorObjC
mirrors.test("ObjC") {
// Some Foundation classes lie about their ivars, which would crash
// a mirror; make sure we are not automatically exposing ivars of
// Objective-C classes from the default mirror implementation.
expectEqual(0, Mirror(reflecting: HasIVars()).children.count)
}
#endif
mirrors.test("String.init") {
expectEqual("42", String(42))
expectEqual("42", String("42"))
expectEqual("42", String(reflecting: 42))
expectEqual("\"42\"", String(reflecting: "42"))
}
struct a<b> {
enum c{}
}
class d {}
struct e<f> {
var constraints: [Int: a<f>.c] = [:]
}
mirrors.test("field with generic nested type") {
let x = e<d>()
expectTrue(type(of: Mirror(reflecting: x).children.first!.value)
== [Int: a<d>.c].self)
}
runAllTests()