//===--- ModuleAnaluzerNodes.h - Nodes for API differ tool ---------------====//
//
// 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
//
//===----------------------------------------------------------------------===//
//
//  Describing nodes from a swiftmodule file to detect ABI/API breakages.
//
//===----------------------------------------------------------------------===//

#ifndef __SWIFT_ABI_DIGESTER_MODULE_NODES_H__
#define __SWIFT_ABI_DIGESTER_MODULE_NODES_H__

#include "clang/AST/ASTContext.h"
#include "clang/AST/DeclObjC.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Sema/Lookup.h"
#include "clang/Sema/Sema.h"
#include "llvm/ADT/TinyPtrVector.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/Signals.h"
#include "llvm/Support/YAMLParser.h"
#include "llvm/Support/YAMLTraits.h"
#include "swift/AST/Attr.h"
#include "swift/AST/Decl.h"
#include "swift/AST/NameLookup.h"
#include "swift/AST/PrettyStackTrace.h"
#include "swift/AST/USRGeneration.h"
#include "swift/AST/GenericSignature.h"
#include "swift/AST/ProtocolConformance.h"
#include "swift/Basic/ColorUtils.h"
#include "swift/Basic/JSONSerialization.h"
#include "swift/Basic/LLVMInitialize.h"
#include "swift/Basic/STLExtras.h"
#include "swift/Basic/Version.h"
#include "swift/ClangImporter/ClangImporter.h"
#include "swift/Frontend/Frontend.h"
#include "swift/Frontend/PrintingDiagnosticConsumer.h"
#include "swift/IDE/Utils.h"
#include "swift/IDE/APIDigesterData.h"
#include <functional>

namespace swift {
namespace json {
class Output;
}
namespace ide {
namespace api {

class SDKNode;
typedef SDKNode* NodePtr;
typedef std::map<NodePtr, NodePtr> ParentMap;
typedef std::map<NodePtr, NodePtr> NodeMap;
typedef std::vector<NodePtr> NodeVector;
typedef std::vector<CommonDiffItem> DiffVector;
typedef std::vector<TypeMemberDiffItem> TypeMemberDiffVector;
typedef llvm::MapVector<NodePtr, NodePtr> NodePairVector;

// The interface used to visit the SDK tree.
class SDKNodeVisitor {
  friend SDKNode;
protected:
  NodeVector Ancestors;
  virtual void visit(NodePtr Node) = 0;

  NodePtr parent() {
    if (Ancestors.empty())
      return nullptr;
    return Ancestors.back();
  }

  int depth() {
    return Ancestors.size() + 1;
  }
public:
  virtual ~SDKNodeVisitor() = default;
};

enum class NodeMatchReason: uint8_t {

  // Two nodes are matched because they're both roots.
  Root,

  // The first node is missing.
  Added,

  // The second node is missing.
  Removed,

  // The nodes are considered a pair becuase they have same/similar name.
  Name,

  // The nodes are matched because they're in the same order, e.g. ith child of
  // a type declaration.
  Sequential,

  // The first node is a function and it chanaged to a propery as the second
  // node.
  FuncToProperty,

  // The first node is a global variable and the second node is an enum element.
  ModernizeEnum,

  // The first node is a type declaration and the second node is a type alias
  // of another type declaration.
  TypeToTypeAlias,
};

// This map keeps track of updated nodes; thus we can conveniently find out what
// is the counterpart of a node before or after being updated.
class UpdatedNodesMap {
  NodePairVector MapImpl;
  UpdatedNodesMap(const UpdatedNodesMap& that) = delete;
public:
  UpdatedNodesMap() = default;
  NodePtr findUpdateCounterpart(const SDKNode *Node) const;
  void insert(NodePtr Left, NodePtr Right) {
    assert(Left && Right && "Not update operation.");
    MapImpl.insert({Left, Right});
  }
};

// Describing some attributes with ABI/API impact. The addition or removal of these
// attributes is considerred breakage.
struct BreakingAttributeInfo {
  const DeclAttrKind Kind;
  const StringRef Content;
};

struct CheckerOptions {
  bool AvoidLocation;
  bool ABI;
  bool Verbose;
  bool AbortOnModuleLoadFailure;
  bool PrintModule;
  bool SwiftOnly;
  StringRef LocationFilter;
};

class SDKContext {
  llvm::StringSet<> TextData;
  llvm::BumpPtrAllocator Allocator;
  SourceManager SourceMgr;
  DiagnosticEngine Diags;
  UpdatedNodesMap UpdateMap;
  NodeMap TypeAliasUpdateMap;
  NodeMap RevertTypeAliasUpdateMap;
  TypeMemberDiffVector TypeMemberDiffs;

  CheckerOptions Opts;
  std::vector<BreakingAttributeInfo> BreakingAttrs;
  /// This is to cache the equal comparison results between nodes.
  llvm::DenseMap<const SDKNode*, llvm::DenseMap<const SDKNode*, bool>> EqualCache;

public:
  SDKContext(CheckerOptions Options);
  llvm::BumpPtrAllocator &allocator() {
    return Allocator;
  }
  StringRef buffer(StringRef Text) {
    return TextData.insert(Text).first->getKey();
  }
  UpdatedNodesMap &getNodeUpdateMap() {
    return UpdateMap;
  }
  NodeMap &getTypeAliasUpdateMap() {
    return TypeAliasUpdateMap;
  }
  NodeMap &getRevertTypeAliasUpdateMap() {
    return RevertTypeAliasUpdateMap;
  }
  TypeMemberDiffVector &getTypeMemberDiffs() {
    return TypeMemberDiffs;
  }
  SourceManager &getSourceMgr() {
    return SourceMgr;
  }
  DiagnosticEngine &getDiags() {
    return Diags;
  }
  bool isEqual(const SDKNode &Left, const SDKNode &Right);
  bool checkingABI() const { return Opts.ABI; }
  AccessLevel getAccessLevel(const ValueDecl *VD) const;
  const CheckerOptions &getOpts() const { return Opts; }
  bool shouldIgnore(Decl *D, const Decl* Parent = nullptr) const;
  ArrayRef<BreakingAttributeInfo> getBreakingAttributeInfo() const { return BreakingAttrs; }
  Optional<uint8_t> getFixedBinaryOrder(ValueDecl *VD) const;
  template<class YAMLNodeTy, typename ...ArgTypes>
  void diagnose(YAMLNodeTy node, Diag<ArgTypes...> ID,
                typename detail::PassArgument<ArgTypes>::type... args) {
    auto smRange = node->getSourceRange();
    auto range = SourceRange(SourceLoc(smRange.Start), SourceLoc(smRange.End));
    Diags.diagnose(range.Start, ID, std::forward<ArgTypes>(args)...)
      .highlight(range);
  }
};

enum class KnownTypeKind: uint8_t {
#define KNOWN_TYPE(NAME) NAME,
#include "swift/IDE/DigesterEnums.def"
  Unknown,
};

enum class KnownProtocolKind: uint8_t {
#define KNOWN_PROTOCOL(NAME) NAME,
#include "swift/IDE/DigesterEnums.def"
};

class SDKNodeRoot;
class SDKNodeDeclGetter;
class SDKNodeDeclSetter;
struct SDKNodeInitInfo;

class SDKNode {
  typedef std::vector<SDKNode*>::iterator ChildIt;
protected:
  SDKContext &Ctx;
  StringRef Name;
  StringRef PrintedName;
  unsigned TheKind : 4;
  NodeVector Children;
  std::set<NodeAnnotation> Annotations;
  std::map<NodeAnnotation, StringRef> AnnotateComments;
  NodePtr Parent = nullptr;
protected:
  SDKNode(SDKNodeInitInfo Info, SDKNodeKind Kind);
  virtual ~SDKNode() = default;
public:
  static SDKNode *constructSDKNode(SDKContext &Ctx, llvm::yaml::MappingNode *Node);
  static void preorderVisit(NodePtr Root, SDKNodeVisitor &Visitor);
  static void postorderVisit(NodePtr Root, SDKNodeVisitor &Visitor);

  bool operator==(const SDKNode &Other) const;
  bool operator!=(const SDKNode &Other) const { return !((*this) == Other); }
  void output(json::Output &out, KeyKind Key, bool Value);
  void output(json::Output &out, KeyKind Key, StringRef Value);

  ArrayRef<NodeAnnotation>
    getAnnotations(std::vector<NodeAnnotation> &Scratch) const;
  bool isLeaf() const { return Children.empty(); }
  SDKNodeKind getKind() const { return SDKNodeKind(TheKind); }
  StringRef getName() const { return Name; }
  bool isNameValid() const { return Name != "_"; }
  StringRef getPrintedName() const { return PrintedName; }
  void removeChild(ChildIt CI) { Children.erase(CI); }
  ChildIt getChildBegin() { return Children.begin(); }
  void annotate(NodeAnnotation Anno) { Annotations.insert(Anno); }
  void annotate(NodeAnnotation Anno, StringRef Comment);
  void removeAnnotate(NodeAnnotation Anno);
  NodePtr getParent() const { return Parent; };
  unsigned getChildrenCount() const { return Children.size(); }
  NodePtr childAt(unsigned I) const;
  void removeChild(NodePtr C);
  StringRef getAnnotateComment(NodeAnnotation Anno) const;
  bool isAnnotatedAs(NodeAnnotation Anno) const;
  void addChild(SDKNode *Child);
  NodeVector& getChildren() { return Children; }
  ArrayRef<SDKNode*> getChildren() const { return Children; }
  bool hasSameChildren(const SDKNode &Other) const;
  unsigned getChildIndex(const SDKNode *Child) const;
  SDKNode* getOnlyChild() const;
  SDKContext &getSDKContext() const { return Ctx; }
  SDKNodeRoot *getRootNode() const;
  virtual void jsonize(json::Output &Out);
  virtual void diagnose(SDKNode *Right) {};
  template <typename T> const T *getAs() const {
    if (T::classof(this))
      return static_cast<const T*>(this);
    llvm_unreachable("incompatible types");
  }
  template <typename T> T *getAs() {
    if (T::classof(this))
      return static_cast<T*>(this);
    llvm_unreachable("incompatible types");
  }
};

class SDKNodeDecl: public SDKNode {
  DeclKind DKind;
  StringRef Usr;
  StringRef Location;
  StringRef ModuleName;
  std::vector<DeclAttrKind> DeclAttributes;
  bool IsImplicit;
  bool IsStatic;
  bool IsDeprecated;
  bool IsProtocolReq;
  bool IsOverriding;
  bool IsOpen;
  bool IsInternal;
  uint8_t ReferenceOwnership;
  StringRef GenericSig;
  Optional<uint8_t> FixedBinaryOrder;

protected:
  SDKNodeDecl(SDKNodeInitInfo Info, SDKNodeKind Kind);
  virtual ~SDKNodeDecl() = default;
public:
  StringRef getUsr() const { return Usr; }
  StringRef getLocation() const { return Location; }
  StringRef getModuleName() const {return ModuleName;}
  StringRef getHeaderName() const;
  ArrayRef<DeclAttrKind> getDeclAttributes() const;
  bool hasAttributeChange(const SDKNodeDecl &Another) const;
  swift::ReferenceOwnership getReferenceOwnership() const {
    return swift::ReferenceOwnership(ReferenceOwnership);
  }
  bool isObjc() const { return Usr.startswith("c:"); }
  static bool classof(const SDKNode *N);
  DeclKind getDeclKind() const { return DKind; }
  void printFullyQualifiedName(llvm::raw_ostream &OS) const;
  StringRef getFullyQualifiedName() const;
  bool isDeprecated() const { return IsDeprecated; };
  bool isProtocolRequirement() const { return IsProtocolReq; }
  bool isNonOptionalProtocolRequirement() const;
  bool hasDeclAttribute(DeclAttrKind DAKind) const;
  bool isImplicit() const { return IsImplicit; };
  bool isStatic() const { return IsStatic; };
  bool isOverriding() const { return IsOverriding; };
  bool isOptional() const { return hasDeclAttribute(DeclAttrKind::DAK_Optional); }
  bool isOpen() const { return IsOpen; }
  bool isInternal() const { return IsInternal; }
  StringRef getGenericSignature() const { return GenericSig; }
  StringRef getScreenInfo() const;
  bool hasFixedBinaryOrder() const { return FixedBinaryOrder.hasValue(); }
  uint8_t getFixedBinaryOrder() const { return *FixedBinaryOrder; }
  virtual void jsonize(json::Output &Out) override;
  virtual void diagnose(SDKNode *Right) override;
};

class SDKNodeRoot: public SDKNode {
  /// This keeps track of all decl descendants with USRs.
  llvm::StringMap<llvm::SmallSetVector<SDKNodeDecl*, 2>> DescendantDeclTable;

public:
  SDKNodeRoot(SDKNodeInitInfo Info);
  static SDKNode *getInstance(SDKContext &Ctx);
  static bool classof(const SDKNode *N);
  void registerDescendant(SDKNode *D);
  ArrayRef<SDKNodeDecl*> getDescendantsByUsr(StringRef Usr) {
    return DescendantDeclTable[Usr].getArrayRef();
  }
};

class SDKNodeType: public SDKNode {
  std::vector<TypeAttrKind> TypeAttributes;
  bool HasDefaultArg;

  // Empty() implies "Default"
  StringRef ParamValueOwnership;

protected:
  SDKNodeType(SDKNodeInitInfo Info, SDKNodeKind Kind);
  ~SDKNodeType() = default;
public:
  bool hasTypeAttribute(TypeAttrKind DAKind) const;
  KnownTypeKind getTypeKind() const;
  void addTypeAttribute(TypeAttrKind AttrKind);
  ArrayRef<TypeAttrKind> getTypeAttributes() const;
  SDKNodeDecl *getClosestParentDecl() const;

  // When the type node represents a function parameter, this function returns
  // whether the parameter has a default value.
  bool hasDefaultArgument() const { return HasDefaultArg; }
  bool isTopLevelType() const { return !isa<SDKNodeType>(getParent()); }
  StringRef getTypeRoleDescription() const;
  StringRef getParamValueOwnership() const;
  static bool classof(const SDKNode *N);
  virtual void jsonize(json::Output &Out) override;
  virtual void diagnose(SDKNode *Right) override;
  bool hasAttributeChange(const SDKNodeType &Another) const;
};

class SDKNodeTypeNominal : public SDKNodeType {
  StringRef USR;
public:
  SDKNodeTypeNominal(SDKNodeInitInfo Info);
  // Get the usr of the correspoding nominal type decl.
  StringRef getUsr() const { return USR; }
  static bool classof(const SDKNode *N);
  void jsonize(json::Output &Out) override;
};

class SDKNodeTypeFunc : public SDKNodeType {
public:
  SDKNodeTypeFunc(SDKNodeInitInfo Info);
  bool isEscaping() const { return hasTypeAttribute(TypeAttrKind::TAK_noescape); }
  static bool classof(const SDKNode *N);
  void diagnose(SDKNode *Right) override;
};

class SDKNodeTypeAlias : public SDKNodeType {
public:
  SDKNodeTypeAlias(SDKNodeInitInfo Info);
  const SDKNodeType *getUnderlyingType() const {
    return getOnlyChild()->getAs<SDKNodeType>();
  }
  static bool classof(const SDKNode *N);
};

class SDKNodeVectorViewer {
  ArrayRef<SDKNode*> Collection;
  llvm::function_ref<bool(NodePtr)> Selector;
  typedef ArrayRef<SDKNode*>::iterator VectorIt;
  VectorIt getNext(VectorIt Start);
  class ViewerIterator;

public:
  SDKNodeVectorViewer(ArrayRef<SDKNode*> Collection,
                      llvm::function_ref<bool(NodePtr)> Selector) :
                        Collection(Collection),
                        Selector(Selector) {}
  ViewerIterator begin();
  ViewerIterator end();
};

class SDKNodeVectorViewer::ViewerIterator :
    public std::iterator<std::input_iterator_tag, VectorIt> {
  SDKNodeVectorViewer &Viewer;
  VectorIt P;
public:
  ViewerIterator(SDKNodeVectorViewer &Viewer, VectorIt P) : Viewer(Viewer), P(P) {}
  ViewerIterator(const ViewerIterator& mit) : Viewer(mit.Viewer), P(mit.P) {}
  ViewerIterator& operator++();
  ViewerIterator operator++(int) {ViewerIterator tmp(*this); operator++(); return tmp;}
  bool operator==(const ViewerIterator& rhs) {return P==rhs.P;}
  bool operator!=(const ViewerIterator& rhs) {return P!=rhs.P;}
  const NodePtr& operator*() {return *P;}
};

class SDKNodeDeclType: public SDKNodeDecl {
  StringRef SuperclassUsr;
  std::vector<StringRef> SuperclassNames;
  std::vector<SDKNode*> Conformances;
  StringRef EnumRawTypeName;
public:
  SDKNodeDeclType(SDKNodeInitInfo Info);
  static bool classof(const SDKNode *N);
  StringRef getSuperClassUsr() const { return SuperclassUsr; }
  ArrayRef<StringRef> getClassInheritanceChain() const { return SuperclassNames; }
  void addConformance(SDKNode *Conf);
  ArrayRef<SDKNode*> getConformances() const { return Conformances; }
  NodeVector getConformances() { return Conformances; }
  StringRef getSuperClassName() const {
    return SuperclassNames.empty() ? StringRef() : SuperclassNames.front();
  };

#define NOMINAL_TYPE_DECL(ID, PARENT) \
  bool is##ID() const { return getDeclKind() == DeclKind::ID; }
#define DECL(ID, PARENT)
#include "swift/AST/DeclNodes.def"

  StringRef getEnumRawTypeName() const {
    assert(isEnum());
    return EnumRawTypeName;
  }

  Optional<SDKNodeDeclType*> getSuperclass() const;

  /// Finding the node through all children, including the inheritted ones,
  /// whose printed name matches with the given name.
  Optional<SDKNodeDecl*> lookupChildByPrintedName(StringRef Name) const;
  SDKNodeType *getRawValueType() const;
  bool isConformingTo(KnownProtocolKind Kind) const;
  void jsonize(json::Output &out) override;
  void diagnose(SDKNode *Right) override;
};

/// Keeps track of a conformance; the children of this node are
/// SDKNodeTypeWitness. The conformance node should have no parent since
/// they are stored as an additional property in SDKNodeDeclType.
/// The SDKNode part of the conformance node is constructed using the protocol
/// in the conformance, thus getName() will give us the name of the protocol.
class SDKNodeConformance: public SDKNode {
  SDKNodeDeclType *TypeDecl;
  friend class SDKNodeDeclType;
public:
  SDKNodeConformance(SDKNodeInitInfo Info);
  ArrayRef<SDKNode*> getTypeWitnesses() const { return Children; }
  SDKNodeDeclType *getNominalTypeDecl() const { return TypeDecl; }
  static bool classof(const SDKNode *N);
};

/// Keep track of a type witness of an associated type requirement. These nodes
/// only appear as children of SDKNodeConformance.
/// The SDKNode part of this node is constructed using the associated type decl;
/// thus getName() will give us the name of the associated type. The only child
/// of this node is a type node witnessing the associated type requirement.
class SDKNodeTypeWitness: public SDKNode {
public:
  SDKNodeTypeWitness(SDKNodeInitInfo Info);
  StringRef getWitnessedTypeName() const;
  SDKNodeType *getUnderlyingType() const;
  static bool classof(const SDKNode *N);
};

class SDKNodeDeclOperator : public SDKNodeDecl {
public:
  SDKNodeDeclOperator(SDKNodeInitInfo Info);
  static bool classof(const SDKNode *N);
  void diagnose(SDKNode *Right) override;
};

class SDKNodeDeclTypeAlias : public SDKNodeDecl {
public:
  SDKNodeDeclTypeAlias(SDKNodeInitInfo Info);
  const SDKNodeType* getUnderlyingType() const {
    return getOnlyChild()->getAs<SDKNodeType>();
  }
  static bool classof(const SDKNode *N);
};

class SDKNodeDeclAssociatedType: public SDKNodeDecl {
public:
  SDKNodeDeclAssociatedType(SDKNodeInitInfo Info);
  const SDKNodeType* getDefault() const {
    return getChildrenCount() ? getOnlyChild()->getAs<SDKNodeType>(): nullptr;
  }
  static bool classof(const SDKNode *N);
};

class SDKNodeDeclVar : public SDKNodeDecl {
  bool IsLet;
  bool HasStorage;
  bool HasDidSet;
  bool HasWillSet;
public:
  SDKNodeDeclVar(SDKNodeInitInfo Info);
  static bool classof(const SDKNode *N);
  SDKNodeDeclGetter *getGetter() const;
  SDKNodeDeclSetter *getSetter() const;
  SDKNodeType *getType() const;
  bool isLet() const { return IsLet; }
  void jsonize(json::Output &Out) override;
  void diagnose(SDKNode *Right) override;
  bool hasStorage() const { return HasStorage; }
  bool hasDidSet() const { return HasDidSet; }
  bool hasWillSet() const { return HasWillSet; }
};

class SDKNodeDeclAbstractFunc : public SDKNodeDecl {
  bool IsThrowing;
  Optional<uint8_t> SelfIndex;

protected:
  SDKNodeDeclAbstractFunc(SDKNodeInitInfo Info, SDKNodeKind Kind);
  virtual ~SDKNodeDeclAbstractFunc() = default;
public:
  bool isThrowing() const { return IsThrowing; }
  uint8_t getSelfIndex() const { return SelfIndex.getValue(); }
  Optional<uint8_t> getSelfIndexOptional() const { return SelfIndex; }
  bool hasSelfIndex() const { return SelfIndex.hasValue(); }
  static bool classof(const SDKNode *N);
  virtual void jsonize(json::Output &out) override;
  static StringRef getTypeRoleDescription(SDKContext &Ctx, unsigned Index);
  virtual void diagnose(SDKNode *Right) override;
};

class SDKNodeDeclSubscript: public SDKNodeDeclAbstractFunc {
  bool HasSetter;
  bool HasStorage;
  bool HasDidSet;
  bool HasWillSet;
public:
  SDKNodeDeclSubscript(SDKNodeInitInfo Info);
  static bool classof(const SDKNode *N);
  bool hasSetter() const { return HasSetter; }
  bool hasStorage() const { return HasStorage; }
  void jsonize(json::Output &Out) override;
  void diagnose(SDKNode *Right) override;
  bool hasDidSet() const { return HasDidSet; }
  bool hasWillSet() const { return HasWillSet; }
};

class SDKNodeDeclFunction: public SDKNodeDeclAbstractFunc {
  StringRef FuncSelfKind;
public:
  SDKNodeDeclFunction(SDKNodeInitInfo Info);
  SDKNode *getReturnType() { return *getChildBegin(); }
  StringRef getSelfAccessKind() const { return FuncSelfKind; }
  static bool classof(const SDKNode *N);
  void jsonize(json::Output &Out) override;
  void diagnose(SDKNode *Right) override;
};

class SDKNodeDeclConstructor: public SDKNodeDeclAbstractFunc {
public:
  SDKNodeDeclConstructor(SDKNodeInitInfo Info);
  static bool classof(const SDKNode *N);
};

class SDKNodeDeclGetter: public SDKNodeDeclAbstractFunc {
public:
  SDKNodeDeclGetter(SDKNodeInitInfo Info);
  static bool classof(const SDKNode *N);
};

class SDKNodeDeclSetter: public SDKNodeDeclAbstractFunc {
public:
  SDKNodeDeclSetter(SDKNodeInitInfo Info);
  static bool classof(const SDKNode *N);
};

// The additional information we need for a type node in the digest.
// We use type node to represent entities more than types, e.g. parameters, so
// this struct is necessary to pass down to create a type node.
struct TypeInitInfo {
  bool IsImplicitlyUnwrappedOptional = false;
  bool hasDefaultArgument = false;
  StringRef ValueOwnership;
};

class SwiftDeclCollector: public VisibleDeclConsumer {
  SDKContext &Ctx;
  std::vector<std::unique_ptr<llvm::MemoryBuffer>> OwnedBuffers;
  SDKNode *RootNode;
  llvm::SetVector<Decl*> KnownDecls;
  // Collected and sorted after we get all of them.
  std::vector<ValueDecl *> ClangMacros;
  std::set<ExtensionDecl*> HandledExtensions;
public:
  void visitAllRoots(SDKNodeVisitor &Visitor) {
    SDKNode::preorderVisit(RootNode, Visitor);
  }
  SwiftDeclCollector(SDKContext &Ctx) : Ctx(Ctx),
    RootNode(SDKNodeRoot::getInstance(Ctx)) {}

  // Construct all roots vector from a given file where a forest was
  // previously dumped.
  void deSerialize(StringRef Filename);

  // Serialize the content of all roots to a given file using JSON format.
  void serialize(StringRef Filename);

  // After collecting decls, either from imported modules or from a previously
  // serialized JSON file, using this function to get the root of the SDK.
  SDKNodeRoot* getSDKRoot() { return static_cast<SDKNodeRoot*>(RootNode); }

  void printTopLevelNames();

  void addConformancesToTypeDecl(SDKNodeDeclType *Root, NominalTypeDecl* NTD);
  void addMembersToRoot(SDKNode *Root, IterableDeclContext *Context);

  SDKNode *constructTypeWitnessNode(AssociatedTypeDecl *Assoc, Type Ty);
  SDKNode *constructConformanceNode(ProtocolConformance *Conform);
  SDKNode *constructSubscriptDeclNode(SubscriptDecl *SD);
  SDKNode *constructAssociatedTypeNode(AssociatedTypeDecl *ATD);
  SDKNode *constructTypeAliasNode(TypeAliasDecl *TAD);
  SDKNode *constructVarNode(ValueDecl *VD);
  SDKNode *constructExternalExtensionNode(NominalTypeDecl *NTD,
                                          ArrayRef<ExtensionDecl*> AllExts);
  SDKNode *constructTypeDeclNode(NominalTypeDecl *NTD);
  SDKNode *constructInitNode(ConstructorDecl *CD);
  SDKNode *constructFunctionNode(FuncDecl* FD, SDKNodeKind Kind);
  SDKNode *constructOperatorDeclNode(OperatorDecl *OD);
  std::vector<SDKNode*> createParameterNodes(ParameterList *PL);
  SDKNode *constructTypeNode(Type T, TypeInitInfo Info = TypeInitInfo());
  void processValueDecl(ValueDecl *VD);
  void foundDecl(ValueDecl *VD, DeclVisibilityKind Reason) override;
  void processDecl(Decl *D);
public:
  void lookupVisibleDecls(ArrayRef<ModuleDecl *> Modules);
};

int dumpSwiftModules(const CompilerInvocation &InitInvok,
                     const llvm::StringSet<> &ModuleNames,
                     StringRef OutputDir,
                     const std::vector<std::string> PrintApis,
                     CheckerOptions Opts);

int dumpSDKContent(const CompilerInvocation &InitInvok,
                   const llvm::StringSet<> &ModuleNames,
                   StringRef OutputFile, CheckerOptions Opts);

/// Mostly for testing purposes, this function de-serializes the SDK dump in
/// dumpPath and re-serialize them to OutputPath. If the tool performs correctly,
/// the contents in dumpPath and OutputPath should be identical.
int deserializeSDKDump(StringRef dumpPath, StringRef OutputPath,
                       CheckerOptions Opts);

int findDeclUsr(StringRef dumpPath, CheckerOptions Opts);

void nodeSetDifference(ArrayRef<SDKNode*> Left, ArrayRef<SDKNode*> Right,
  NodeVector &LeftMinusRight, NodeVector &RightMinusLeft);

} // end of abi namespace
} // end of ide namespace
} // end of Swift namespace

#endif
