static word computeAttributeTypeFlags()

in runtime/type-builtins.cpp [117:230]


static word computeAttributeTypeFlags(Thread* thread, const Type& type,
                                      SymbolId name, word flags) {
  Runtime* runtime = thread->runtime();
  // Custom MROs can contain types that are not part of the subclass hierarchy
  // which does not fit our cache invalidation strategy for the flags. Be safe
  // and do not set any!
  if (flags & Type::Flag::kHasCustomMro) {
    return flags & ~Type::kAttributeFlags;
  }
  if (name == ID(__getattribute__)) {
    RawObject value = typeLookupInMroById(thread, *type, name);
    if (value == runtime->objectDunderGetattribute()) {
      flags |= Type::Flag::kHasObjectDunderGetattribute;
    } else {
      flags &= ~Type::Flag::kHasObjectDunderGetattribute;
    }
    if (value == runtime->typeDunderGetattribute()) {
      flags |= Type::Flag::kHasTypeDunderGetattribute;
    } else {
      flags &= ~Type::Flag::kHasTypeDunderGetattribute;
    }
    if (value == runtime->moduleDunderGetattribute()) {
      flags |= Type::Flag::kHasModuleDunderGetattribute;
    } else {
      flags &= ~Type::Flag::kHasModuleDunderGetattribute;
    }
    return flags;
  }
  if (name == ID(__new__)) {
    RawObject value = typeLookupInMroById(thread, *type, name);
    if (value == runtime->objectDunderNew()) {
      flags |= Type::Flag::kHasObjectDunderNew;
    } else {
      flags &= ~Type::Flag::kHasObjectDunderNew;
    }
    return flags;
  }
  if (name == ID(__hash__)) {
    RawObject value = typeLookupInMroById(thread, *type, name);
    if (value == runtime->objectDunderHash()) {
      flags |= Type::Flag::kHasObjectDunderHash;
    } else if (value == runtime->strDunderHash()) {
      flags |= Type::Flag::kHasStrDunderHash;
    } else {
      flags &=
          ~(Type::Flag::kHasObjectDunderHash | Type::Flag::kHasStrDunderHash);
    }
    return flags;
  }
  if (name == ID(__bool__)) {
    RawObject value = typeLookupInMroById(thread, *type, name);
    if (!value.isErrorNotFound()) {
      flags |= Type::Flag::kHasDunderBool;
    } else {
      flags &= ~Type::Flag::kHasDunderBool;
    }
    return flags;
  }
  if (name == ID(__len__)) {
    RawObject value = typeLookupInMroById(thread, *type, name);
    if (!value.isErrorNotFound()) {
      flags |= Type::Flag::kHasDunderLen;
    } else {
      flags &= ~Type::Flag::kHasDunderLen;
    }
    return flags;
  }
  if (name == ID(__class__)) {
    RawObject value = typeLookupInMroById(thread, *type, name);
    if (value == runtime->objectDunderClass()) {
      flags |= Type::Flag::kHasObjectDunderClass;
    } else {
      flags &= ~Type::Flag::kHasObjectDunderClass;
    }
    return flags;
  }
  if (name == ID(__eq__)) {
    RawObject value = typeLookupInMroById(thread, *type, name);
    if (value == runtime->objectDunderEq()) {
      flags |= Type::Flag::kHasObjectDunderEq;
    } else {
      flags &= ~Type::Flag::kHasObjectDunderEq;
    }
    return flags;
  }
  if (name == ID(__get__)) {
    RawObject value = typeLookupInMroById(thread, *type, name);
    if (!value.isErrorNotFound()) {
      flags |= Type::Flag::kHasDunderGet;
    } else {
      flags &= ~Type::Flag::kHasDunderGet;
    }
    return flags;
  }
  if (name == ID(__set__)) {
    RawObject value = typeLookupInMroById(thread, *type, name);
    if (!value.isErrorNotFound()) {
      flags |= Type::Flag::kHasDunderSet;
    } else {
      flags &= ~Type::Flag::kHasDunderSet;
    }
    return flags;
  }
  if (name == ID(__delete__)) {
    RawObject value = typeLookupInMroById(thread, *type, name);
    if (!value.isErrorNotFound()) {
      flags |= Type::Flag::kHasDunderDelete;
    } else {
      flags &= ~Type::Flag::kHasDunderDelete;
    }
    return flags;
  }
  return flags;
}