Repository: apple/swift
File: lib/AST/ASTPrinter.cpp (C++)

Code before:
  return ED->getLocFromSource() == nonSendable->AtLoc;
}

bool ShouldPrintChecker::shouldPrint(const Decl *D,
                                     const PrintOptions &Options) {
  // Skip constructors defined in Objective-C categories that are not
  // publicly imported according to the interface type being generated
  if (auto *CD = dyn_cast<ConstructorDecl>(D)) {
    if (Options.IsForSwiftInterface && Options.CurrentModule) {
      // For inherited constructors, check the original declaration
      auto *checkDecl = CD;
      if (auto *overridden = CD->getOverriddenDecl()) {
        checkDecl = overridden;
      }
      auto definingModule = checkDecl->getModuleContext();
      // Check how the defining module is imported
      if (auto *SF = CD->getDeclContext()->getParentSourceFile()) {
        // Don't check import status for self-imports
        if (definingModule != SF->getParentModule()) {
          auto restrictedKind = SF->getRestrictedImportKind(definingModule);
          // Skip inherited constructors if defining module is hidden
          if (restrictedKind != RestrictedImportKind::None)
            return false;
          // Check access level
          if (auto importAccess = SF->getImportAccessLevel(definingModule)) {
            auto accessLevel = importAccess->accessLevel;
            // Internal and below: skip in all interfaces
            if (accessLevel < AccessLevel::Package)
              return false;
            // Package: skip in non-package interfaces only
            if (accessLevel == AccessLevel::Package &&
                !Options.printPackageInterface())
              return false;
          }
        }
      }
    }
  }

  if (auto *ED = dyn_cast<ExtensionDecl>(D)) {
    if (Options.printExtensionContentAsMembers(ED))
      return false;
  }

  if (Options.SkipMissingMemberPlaceholders && isa<MissingMemberDecl>(D))
    return false;

  if (Options.SkipDeinit && isa<DestructorDecl>(D)) {
    return false;
  }


Review comment (suggestion):
Since you've added proper support for all kinds of hidden dependencies, we might as well check specifically for `restrictedKind == RestrictedImportKind::SPIOnly` and whether we are in `printPublicInterface()` mode to keep those in private and package swiftinterface.

Code after:
  return ED->getLocFromSource() == nonSendable->AtLoc;
}

bool ShouldPrintChecker::shouldPrint(const Decl *D,
                                     const PrintOptions &Options) {
  // Skip constructors defined in Objective-C categories that are not
  // publicly imported according to the interface type being generated
  if (auto *CD = dyn_cast<ConstructorDecl>(D)) {
    if (CD->isImplicit() && Options.IsForSwiftInterface &&
        Options.CurrentModule) {
      // For inherited constructors, check the original declaration
      auto *checkDecl = CD;
      if (auto *overridden = CD->getOverriddenDecl()) {
        checkDecl = overridden;
      }
      auto definingModule = checkDecl->getModuleContext();
      // Check how the defining module is imported
      if (auto *SF = CD->getDeclContext()->getParentSourceFile()) {
        // Don't check import status for self-imports
        if (definingModule != SF->getParentModule()) {
          auto restrictedKind = SF->getRestrictedImportKind(definingModule);
          switch (restrictedKind) {
          // MissingImport and ImplementationOnly: skip in all interfaces
          case RestrictedImportKind::MissingImport:
          case RestrictedImportKind::ImplementationOnly:
            return false;
          // SPIOnly: skip in public interfaces
          case RestrictedImportKind::SPIOnly:
            if (Options.printPublicInterface())
              return false;
            break;
          case RestrictedImportKind::None:
            break;
          }
          // Check access level
          if (auto importAccess = SF->getImportAccessLevel(definingModule)) {
            auto accessLevel = importAccess->accessLevel;
            switch (accessLevel) {
            // Internal and below: skip in all interfaces
            case AccessLevel::Private:
            case AccessLevel::FilePrivate:
            case AccessLevel::Internal:
              return false;
            // Package: skip in non-package interfaces only
            case AccessLevel::Package:
              if (!Options.printPackageInterface())
                return false;
              break;
            default:
              break;
            }