Swift源码分析Mirror(一)

Swift原生反射Mirror分析

  1. swift和c++函数进行通信,即@_silgen_name修饰符会通知swift编译器将这个swift函数映射成C++函数的符号。
  2. 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)'")
    }
    ...
  }
}
  1. 反射自身
  2. 如果要获取父类,则要调另一个属性superclassMirror递归一下:
let mirror = Mirror(reflecting: ...)
for mirror in sequence(first: mirror, next: { $0.superclassMirror }) {
    ...
}
  1. _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 { ... }
 ...
};
  1. 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);
  });
}
  1. Children(children)
public typealias Children = AnyCollection<Child>
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容