Swift原生反射Mirror分析
- swift和c++函数进行通信,即@_silgen_name修饰符会通知swift编译器将这个swift函数映射成C++函数的符号。
- Mirror主要涉及到stdlib/public/core/ReflectionMirror.swift和stdlib/public/runtime/ReflectionMirror.cpp文件。
- 首先来看看Mirror.swift这个结构体:
public struct Mirror {
/// 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?
internal let _makeSuperclassMirror: () -> Mirror?
internal let _defaultDescendantRepresentation: _DefaultDescendantRepresentation
public init(reflecting subject: Any) {
if case let customized as CustomReflectable = subject {
self = customized.customMirror
} else {
self = Mirror(internalReflecting: subject)
}
}
public init<Subject, C: Collection>(
_ subject: Subject,
children: C,
displayStyle: DisplayStyle? = nil,
ancestorRepresentation: AncestorRepresentation = .generated
) where C.Element == Child {
...
}
public init<Subject, C: Collection>(
_ subject: Subject,
unlabeledChildren: C,
displayStyle: DisplayStyle? = nil,
ancestorRepresentation: AncestorRepresentation = .generated
) {
...
}
public init<Subject>(
_ subject: Subject,
children: KeyValuePairs<String, Any>,
displayStyle: DisplayStyle? = nil,
ancestorRepresentation: AncestorRepresentation = .generated
) {
...
}
/// A mirror of the subject's superclass, if one exists.
public var superclassMirror: Mirror? {
return _makeSuperclassMirror()
}
public typealias Child = (label: String?, value: Any)
public typealias Children = AnyCollection<Mirror.Child>
}
- 构造方法
public init(reflecting subject: Any) {
// 如果遵循了CustomReflectable协议,则返回customMirror属性
if case let customized as CustomReflectable = subject {
self = customized.customMirror
} else {
self = Mirror(internalReflecting: subject)
}
}
- CustomReflectable是个协议,可在Mirror.swift里找到
/// A type that explicitly supplies its own mirror.
///
/// You can create a mirror for any type using the `Mirror(reflecting:)`
/// 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 }
}
- 在Mirrors.swift里你会发现很多类型都遵循这个协议
extension Double: CustomReflectable {
/// A mirror that reflects the `Double` instance.
public var customMirror: Mirror {
return Mirror(self, unlabeledChildren: EmptyCollection<Void>())
}
}
extension Bool: CustomReflectable {
/// A mirror that reflects the `Bool` instance.
public var customMirror: Mirror {
return Mirror(self, unlabeledChildren: EmptyCollection<Void>())
}
}
extension String: CustomReflectable {
/// A mirror that reflects the `String` instance.
public var customMirror: Mirror {
return Mirror(self, unlabeledChildren: EmptyCollection<Void>())
}
}
...
- 协议方法大部分返回一个Mirror(self, unlabeledChildren: EmptyCollection<Void>()),这里的EmptyCollection是一个结构体。
/// 类型为Element但始终为空的集合
@frozen // trivial-implementation
public struct EmptyCollection<Element> {
// no properties
/// Creates an instance.
@inlinable // trivial-implementation
public init() {}
}
- Mirror(internalReflecting: subject): stdlib/public/core/ReflectionMirror.swift的133行
extension Mirror {
internal init(internalReflecting subject: Any,
subjectType: Any.Type? = nil,
customAncestor: Mirror? = nil)
{
//获subject的类型信息
let subjectType = subjectType ?? _getNormalizedType(subject, type: type(of: subject))
let childCount = swift_reflectionMirror_subscriptCount(subject, type: subjectType)
let children = (0 ..< childCount).lazy.map({
getChild(of: subject, type: subjectType, index: $0)
})
self.children = Children(children)
self.subjectType = subjectType
...
let rawDisplayStyle = _getDisplayStyle(subject)
switch UnicodeScalar(Int(rawDisplayStyle)) {
case "c": self.displayStyle = .class
case "e": self.displayStyle = .enum
case "s": self.displayStyle = .struct
case "t": self.displayStyle = .tuple
case "\0": self.displayStyle = nil
default: preconditionFailure("Unknown raw display style '\(rawDisplayStyle)'")
}
...
}
}
- 反射自身
- 如果要获取父类,则要调另一个属性superclassMirror递归一下:
let mirror = Mirror(reflecting: ...)
for mirror in sequence(first: mirror, next: { $0.superclassMirror }) {
...
}
- _getNormalizedType(subject, type: type(of: subject))、 _getChildCount(subject, type: subjectType)
@_silgen_name("swift_reflectionMirror_normalizedType")
internal func _getNormalizedType<T>(_: T, type: Any.Type) -> Any.Type
// func _getNormalizedType<T>(_: T, type: Any.Type) -> Any.Type
SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_API
const Metadata *swift_reflectionMirror_normalizedType(OpaqueValue *value, const Metadata *type, const Metadata *T) {
return call(value, T, type, [](ReflectionMirrorImpl *impl) { return impl->type; });
}
/// -----------------------分割线---------------------------
@_silgen_name("swift_reflectionMirror_count")
internal func _getChildCount<T>(_: T, type: Any.Type) -> Int
// func _getChildCount<T>(_: T, type: Any.Type) -> Int
SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_API
intptr_t swift_reflectionMirror_count(OpaqueValue *value,const Metadata *type, const Metadata *T) {
return call(value, T, type, [](ReflectionMirrorImpl *impl) {
return impl->count();
});
}
3.1. call方法返回元数据 *****
template<typename F>
auto call(OpaqueValue *passedValue, const Metadata *T, const Metadata *passedType,
const F &f) -> decltype(f(nullptr))
{
const Metadata *type;
OpaqueValue *value;
std::tie(type, value) = unwrapExistential(T, passedValue);
if (passedType != nullptr) {
type = passedType;
}
auto call = [&](ReflectionMirrorImpl *impl) {
impl->type = type;
impl->value = value;
auto result = f(impl);
return result;
};
auto callClass = [&] {
if (passedType == nullptr) {
// Get the runtime type of the object.
const void *obj = *reinterpret_cast<const void * const *>(value);
auto isa = _swift_getClass(obj);
// Look through artificial subclasses.
while (isa->isTypeMetadata() && isa->isArtificialSubclass()) {
isa = isa->Superclass;
}
passedType = isa;
}
#if SWIFT_OBJC_INTEROP
// If this is a pure ObjC class, reflect it using ObjC's runtime facilities.
// ForeignClass (e.g. CF classes) manifests as a NULL class object.
auto *classObject = passedType->getClassObject();
if (classObject == nullptr || !classObject->isTypeMetadata()) {
ObjCClassImpl impl;
return call(&impl);
}
#endif
// Otherwise, use the native Swift facilities.
ClassImpl impl;
return call(&impl);
};
switch (type->getKind()) {
case MetadataKind::Tuple: {
TupleImpl impl;
return call(&impl);
}
case MetadataKind::Struct: {
StructImpl impl;
return call(&impl);
}
case MetadataKind::Enum:
case MetadataKind::Optional: {
EnumImpl impl;
return call(&impl);
}
case MetadataKind::ObjCClassWrapper:
case MetadataKind::ForeignClass:
case MetadataKind::Class: {
return callClass();
}
case MetadataKind::Metatype:
case MetadataKind::ExistentialMetatype: {
MetatypeImpl impl;
return call(&impl);
}
...
}
static std::tuple<const Metadata *, OpaqueValue *>
unwrapExistential(const Metadata *T, OpaqueValue *Value) {
// If the value is an existential container, look through it to reflect the
// contained value.
// TODO: Should look through existential metatypes too, but it doesn't
// really matter yet since we don't have any special mirror behavior for
// concrete metatypes yet.
while (T->getKind() == MetadataKind::Existential) {
auto *existential = static_cast<const ExistentialTypeMetadata *>(T);
// Unwrap the existential container.
T = existential->getDynamicType(Value);
Value = existential->projectValue(Value);
// Existential containers can end up nested in some cases due to generic
// abstraction barriers. Repeat in case we have a nested existential.
}
return std::make_tuple(T, Value);
}
a. 声明了class和非class的call函数
b. 这回调函数都涉及到参数ReflectionMirrorImpl
c. 根据不同的MetadataKind有不同的Impl
3.2. ReflectionMirrorImpl是个抽象类,内基本全是虚函数:
// Abstract base class for reflection implementations.
struct ReflectionMirrorImpl {
const Metadata *type;
OpaqueValue *value;
virtual char displayStyle() = 0;
virtual intptr_t count() = 0;
virtual intptr_t childOffset(intptr_t index) = 0;
virtual const FieldType childMetadata(intptr_t index,
const char **outName,
void (**outFreeFunc)(const char *)) = 0;
virtual AnyReturn subscript(intptr_t index, const char **outName,
void (**outFreeFunc)(const char *)) = 0;
virtual const char *enumCaseName() { return nullptr; }
virtual intptr_t recursiveCount() { return count(); }
virtual intptr_t recursiveChildOffset(intptr_t index) { return childOffset(index); }
virtual const FieldType recursiveChildMetadata(intptr_t index,
const char **outName,
void (**outFreeFunc)(const char *))
{
return childMetadata(index, outName, outFreeFunc);
}
}
例如:ClassImpl
struct ClassImpl : ReflectionMirrorImpl {
char displayStyle() override { return 'c'; }
bool hasSuperclassMirror() { ... }
ClassImpl superclassMirror() { ... }
intptr_t count() override { ... }
intptr_t recursiveCount() override { ... }
intptr_t childOffset(intptr_t i) override { ... }
intptr_t recursiveChildOffset(intptr_t i) override { ... }
const FieldType childMetadata(intptr_t i, const char **outName,
void (**outFreeFunc)(const char *)) override { ... }
const FieldType recursiveChildMetadata(intptr_t i,
const char **outName,
void (**outFreeFunc)(const char *)) override { ... }
AnyReturn subscript(intptr_t i, const char **outName,
void (**outFreeFunc)(const char *)) override { ... }
...
};
- getChild(of: subject, type: subjectType, index: $0)
internal func getChild<T>(of value: T, type: Any.Type, index: Int) -> (label: String?, value: Any) {
var nameC: UnsafePointer<CChar>? = nil
var freeFunc: NameFreeFunc? = nil
let value = _getChild(of: value, type: type, index: index, outName: &nameC, outFreeFunc: &freeFunc)
let name = nameC.flatMap({ String(validatingUTF8: $0) })
freeFunc?(nameC)
return (name, value)
}
@_silgen_name("swift_reflectionMirror_subscript")
internal func _getChild<T>(
of: T,
type: Any.Type,
index: Int,
outName: UnsafeMutablePointer<UnsafePointer<CChar>?>,
outFreeFunc: UnsafeMutablePointer<NameFreeFunc?>
) -> Any
AnyReturn swift_reflectionMirror_subscript(OpaqueValue *value, const Metadata *type,
intptr_t index,
const char **outName,
void (**outFreeFunc)(const char *),
const Metadata *T) {
return call(value, T, type, [&](ReflectionMirrorImpl *impl) {
return impl->subscript(index, outName, outFreeFunc);
});
}
- Children(children)
public typealias Children = AnyCollection<Child>