//===- ExtractAPI/DeclarationFragments.h ------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
///
/// \file
/// This file defines the Declaration Fragments related classes.
///
/// Declaration Fragments represent parts of a symbol declaration tagged with
/// syntactic/semantic information.
/// See https://github.com/apple/swift-docc-symbolkit
///
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_EXTRACTAPI_DECLARATION_FRAGMENTS_H
#define LLVM_CLANG_EXTRACTAPI_DECLARATION_FRAGMENTS_H

#include "clang/AST/ASTContext.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/ExprCXX.h"
#include "clang/AST/TypeLoc.h"
#include "clang/Basic/Specifiers.h"
#include "clang/Lex/MacroInfo.h"
#include <vector>

namespace clang {
namespace extractapi {

/// DeclarationFragments is a vector of tagged important parts of a symbol's
/// declaration.
///
/// The fragments sequence can be joined to form spans of declaration text, with
/// attached information useful for purposes like syntax-highlighting etc.
/// For example:
/// \code
///   const -> keyword    "const"
///   int   -> type       "int"
///   pi;   -> identifier "pi"
/// \endcode
class DeclarationFragments {
public:
  DeclarationFragments() = default;

  /// The kind of a fragment.
  enum class FragmentKind {
    /// Unknown fragment kind.
    None,

    Keyword,
    Attribute,
    NumberLiteral,
    StringLiteral,
    Identifier,

    /// Identifier that refers to a type in the context.
    TypeIdentifier,

    /// Parameter that's used as generics in the context. For example template
    /// parameters.
    GenericParameter,

    /// External parameters in Objective-C methods.
    /// For example, \c forKey in
    /// \code{.m}
    ///   - (void) setValue:(Value)value forKey(Key)key
    /// \endcode
    ExternalParam,

    /// Internal/local parameters in Objective-C methods.
    /// For example, \c key in
    /// \code{.m}
    ///   - (void) setValue:(Value)value forKey(Key)key
    /// \endcode
    InternalParam,

    Text,
  };

  /// Fragment holds information of a single fragment.
  struct Fragment {
    std::string Spelling;
    FragmentKind Kind;

    /// The USR of the fragment symbol, if applicable.
    std::string PreciseIdentifier;

    /// The associated declaration, if applicable. This is not intended to be
    /// used outside of libclang.
    const Decl *Declaration;

    Fragment(StringRef Spelling, FragmentKind Kind, StringRef PreciseIdentifier,
             const Decl *Declaration)
        : Spelling(Spelling), Kind(Kind), PreciseIdentifier(PreciseIdentifier),
          Declaration(Declaration) {}
  };

  using FragmentIterator = std::vector<Fragment>::iterator;
  using ConstFragmentIterator = std::vector<Fragment>::const_iterator;

  const std::vector<Fragment> &getFragments() const { return Fragments; }

  FragmentIterator begin() { return Fragments.begin(); }

  FragmentIterator end() { return Fragments.end(); }

  ConstFragmentIterator cbegin() const { return Fragments.cbegin(); }

  ConstFragmentIterator cend() const { return Fragments.cend(); }

  // Add a new Fragment at an arbitrary offset.
  DeclarationFragments &insert(FragmentIterator It, StringRef Spelling,
                               FragmentKind Kind,
                               StringRef PreciseIdentifier = "",
                               const Decl *Declaration = nullptr) {
    Fragments.insert(It,
                     Fragment(Spelling, Kind, PreciseIdentifier, Declaration));
    return *this;
  }

  DeclarationFragments &insert(FragmentIterator It,
                               DeclarationFragments &&Other) {
    Fragments.insert(It, std::make_move_iterator(Other.Fragments.begin()),
                     std::make_move_iterator(Other.Fragments.end()));
    Other.Fragments.clear();
    return *this;
  }

  /// Append a new Fragment to the end of the Fragments.
  ///
  /// \returns a reference to the DeclarationFragments object itself after
  /// appending to chain up consecutive appends.
  DeclarationFragments &append(StringRef Spelling, FragmentKind Kind,
                               StringRef PreciseIdentifier = "",
                               const Decl *Declaration = nullptr) {
    if (Kind == FragmentKind::Text && !Fragments.empty() &&
        Fragments.back().Kind == FragmentKind::Text) {
      // If appending a text fragment, and the last fragment is also text,
      // merge into the last fragment.
      Fragments.back().Spelling.append(Spelling.data(), Spelling.size());
    } else {
      Fragments.emplace_back(Spelling, Kind, PreciseIdentifier, Declaration);
    }
    return *this;
  }

  /// Append another DeclarationFragments to the end.
  ///
  /// Note: \p Other is moved from and cannot be used after a call to this
  /// method.
  ///
  /// \returns a reference to the DeclarationFragments object itself after
  /// appending to chain up consecutive appends.
  DeclarationFragments &append(DeclarationFragments &&Other) {
    Fragments.insert(Fragments.end(),
                     std::make_move_iterator(Other.Fragments.begin()),
                     std::make_move_iterator(Other.Fragments.end()));
    Other.Fragments.clear();
    return *this;
  }

  DeclarationFragments &pop_back() {
    Fragments.pop_back();
    return *this;
  }

  DeclarationFragments &replace(std::string NewSpelling, unsigned Position) {
    Fragments.at(Position).Spelling = NewSpelling;
    return *this;
  }

  /// Append a text Fragment of a space character.
  ///
  /// \returns a reference to the DeclarationFragments object itself after
  /// appending to chain up consecutive appends.
  DeclarationFragments &appendSpace();

  /// Append a text Fragment of a semicolon character.
  ///
  /// \returns a reference to the DeclarationFragments object itself after
  /// appending to chain up consecutive appends.
  DeclarationFragments &appendSemicolon();

  /// Removes a trailing semicolon character if present.
  ///
  /// \returns a reference to the DeclarationFragments object itself after
  /// removing to chain up consecutive operations.
  DeclarationFragments &removeTrailingSemicolon();

  /// Get the string description of a FragmentKind \p Kind.
  static StringRef getFragmentKindString(FragmentKind Kind);

  /// Get the corresponding FragmentKind from string \p S.
  static FragmentKind parseFragmentKindFromString(StringRef S);

  static DeclarationFragments
  getExceptionSpecificationString(ExceptionSpecificationType ExceptionSpec);

  static DeclarationFragments getStructureTypeFragment(const RecordDecl *Decl);

private:
  DeclarationFragments &appendUnduplicatedTextCharacter(char Character);
  std::vector<Fragment> Fragments;
};

class AccessControl {
public:
  AccessControl(std::string Access) : Access(Access) {}
  AccessControl() : Access("public") {}

  const std::string &getAccess() const { return Access; }

  bool empty() const { return Access.empty(); }

private:
  std::string Access;
};

/// Store function signature information with DeclarationFragments of the
/// return type and parameters.
class FunctionSignature {
public:
  FunctionSignature() = default;

  /// Parameter holds the name and DeclarationFragments of a single parameter.
  struct Parameter {
    std::string Name;
    DeclarationFragments Fragments;

    Parameter(StringRef Name, DeclarationFragments Fragments)
        : Name(Name), Fragments(Fragments) {}
  };

  const std::vector<Parameter> &getParameters() const { return Parameters; }
  const DeclarationFragments &getReturnType() const { return ReturnType; }

  FunctionSignature &addParameter(StringRef Name,
                                  DeclarationFragments Fragments) {
    Parameters.emplace_back(Name, Fragments);
    return *this;
  }

  void setReturnType(DeclarationFragments RT) { ReturnType = RT; }

  /// Determine if the FunctionSignature is empty.
  ///
  /// \returns true if the return type DeclarationFragments is empty and there
  /// is no parameter, otherwise false.
  bool empty() const {
    return Parameters.empty() && ReturnType.getFragments().empty();
  }

private:
  std::vector<Parameter> Parameters;
  DeclarationFragments ReturnType;
};

/// A factory class to build DeclarationFragments for different kinds of Decl.
class DeclarationFragmentsBuilder {
public:
  /// Build FunctionSignature for a function-like declaration \c FunctionT like
  /// FunctionDecl, ObjCMethodDecl, or CXXMethodDecl.
  ///
  /// The logic and implementation of building a signature for a FunctionDecl,
  /// CXXMethodDecl, and ObjCMethodDecl are exactly the same, but they do not
  /// share a common base. This template helps reuse the code.
  template <typename FunctionT>
  static FunctionSignature getFunctionSignature(const FunctionT *Function);

  static AccessControl getAccessControl(const Decl *Decl) {
    switch (Decl->getAccess()) {
    case AS_public:
    case AS_none:
      return AccessControl("public");
    case AS_private:
      return AccessControl("private");
    case AS_protected:
      return AccessControl("protected");
    }
    llvm_unreachable("Unhandled access control");
  }

  static DeclarationFragments
  getFragmentsForNamespace(const NamespaceDecl *Decl);

  /// Build DeclarationFragments for a variable declaration VarDecl.
  static DeclarationFragments getFragmentsForVar(const VarDecl *);

  static DeclarationFragments getFragmentsForVarTemplate(const VarDecl *);

  /// Build DeclarationFragments for a function declaration FunctionDecl.
  static DeclarationFragments getFragmentsForFunction(const FunctionDecl *);

  /// Build DeclarationFragments for an enum constant declaration
  /// EnumConstantDecl.
  static DeclarationFragments
  getFragmentsForEnumConstant(const EnumConstantDecl *);

  /// Build DeclarationFragments for an enum declaration EnumDecl.
  static DeclarationFragments getFragmentsForEnum(const EnumDecl *);

  /// Build DeclarationFragments for a field declaration FieldDecl.
  static DeclarationFragments getFragmentsForField(const FieldDecl *);

  /// Build DeclarationFragments for a struct/union record declaration
  /// RecordDecl.
  static DeclarationFragments getFragmentsForRecordDecl(const RecordDecl *);

  static DeclarationFragments getFragmentsForCXXClass(const CXXRecordDecl *);

  static DeclarationFragments
  getFragmentsForSpecialCXXMethod(const CXXMethodDecl *);

  static DeclarationFragments getFragmentsForCXXMethod(const CXXMethodDecl *);

  static DeclarationFragments
  getFragmentsForConversionFunction(const CXXConversionDecl *);

  static DeclarationFragments
  getFragmentsForOverloadedOperator(const CXXMethodDecl *);

  static DeclarationFragments
      getFragmentsForTemplateParameters(ArrayRef<NamedDecl *>);

  static DeclarationFragments getFragmentsForTemplateArguments(
      const ArrayRef<TemplateArgument>, ASTContext &,
      const std::optional<ArrayRef<TemplateArgumentLoc>>);

  static DeclarationFragments getFragmentsForConcept(const ConceptDecl *);

  static DeclarationFragments
  getFragmentsForRedeclarableTemplate(const RedeclarableTemplateDecl *);

  static DeclarationFragments getFragmentsForClassTemplateSpecialization(
      const ClassTemplateSpecializationDecl *);

  static DeclarationFragments getFragmentsForClassTemplatePartialSpecialization(
      const ClassTemplatePartialSpecializationDecl *);

  static DeclarationFragments getFragmentsForVarTemplateSpecialization(
      const VarTemplateSpecializationDecl *);

  static DeclarationFragments getFragmentsForVarTemplatePartialSpecialization(
      const VarTemplatePartialSpecializationDecl *);

  static DeclarationFragments
  getFragmentsForFunctionTemplate(const FunctionTemplateDecl *Decl);

  static DeclarationFragments
  getFragmentsForFunctionTemplateSpecialization(const FunctionDecl *Decl);

  /// Build DeclarationFragments for an Objective-C category declaration
  /// ObjCCategoryDecl.
  static DeclarationFragments
  getFragmentsForObjCCategory(const ObjCCategoryDecl *);

  /// Build DeclarationFragments for an Objective-C interface declaration
  /// ObjCInterfaceDecl.
  static DeclarationFragments
  getFragmentsForObjCInterface(const ObjCInterfaceDecl *);

  /// Build DeclarationFragments for an Objective-C method declaration
  /// ObjCMethodDecl.
  static DeclarationFragments getFragmentsForObjCMethod(const ObjCMethodDecl *);

  /// Build DeclarationFragments for an Objective-C property declaration
  /// ObjCPropertyDecl.
  static DeclarationFragments
  getFragmentsForObjCProperty(const ObjCPropertyDecl *);

  /// Build DeclarationFragments for an Objective-C protocol declaration
  /// ObjCProtocolDecl.
  static DeclarationFragments
  getFragmentsForObjCProtocol(const ObjCProtocolDecl *);

  /// Build DeclarationFragments for a macro.
  ///
  /// \param Name name of the macro.
  /// \param MD the associated MacroDirective.
  static DeclarationFragments getFragmentsForMacro(StringRef Name,
                                                   const MacroDirective *MD);

  /// Build DeclarationFragments for a typedef \p TypedefNameDecl.
  static DeclarationFragments
  getFragmentsForTypedef(const TypedefNameDecl *Decl);

  /// Build sub-heading fragments for a NamedDecl.
  static DeclarationFragments getSubHeading(const NamedDecl *);

  /// Build sub-heading fragments for an Objective-C method.
  static DeclarationFragments getSubHeading(const ObjCMethodDecl *);

  /// Build a sub-heading for macro \p Name.
  static DeclarationFragments getSubHeadingForMacro(StringRef Name);

private:
  DeclarationFragmentsBuilder() = delete;

  /// Build DeclarationFragments for a QualType.
  static DeclarationFragments getFragmentsForType(const QualType, ASTContext &,
                                                  DeclarationFragments &);

  /// Build DeclarationFragments for a Type.
  static DeclarationFragments getFragmentsForType(const Type *, ASTContext &,
                                                  DeclarationFragments &);

  /// Build DeclarationFragments for a NestedNameSpecifier.
  static DeclarationFragments getFragmentsForNNS(const NestedNameSpecifier *,
                                                 ASTContext &,
                                                 DeclarationFragments &);

  /// Build DeclarationFragments for Qualifiers.
  static DeclarationFragments getFragmentsForQualifiers(const Qualifiers quals);

  /// Build DeclarationFragments for a parameter variable declaration
  /// ParmVarDecl.
  static DeclarationFragments getFragmentsForParam(const ParmVarDecl *);

  static DeclarationFragments
  getFragmentsForBlock(const NamedDecl *BlockDecl, FunctionTypeLoc &Block,
                       FunctionProtoTypeLoc &BlockProto,
                       DeclarationFragments &After);
};

template <typename FunctionT>
FunctionSignature
DeclarationFragmentsBuilder::getFunctionSignature(const FunctionT *Function) {
  FunctionSignature Signature;

  DeclarationFragments ReturnType, After;
  ReturnType = getFragmentsForType(Function->getReturnType(),
                                   Function->getASTContext(), After);
  if (isa<FunctionDecl>(Function) &&
      dyn_cast<FunctionDecl>(Function)->getDescribedFunctionTemplate() &&
      StringRef(ReturnType.begin()->Spelling).starts_with("type-parameter")) {
    std::string ProperArgName = Function->getReturnType().getAsString();
    ReturnType.begin()->Spelling.swap(ProperArgName);
  }
  ReturnType.append(std::move(After));
  Signature.setReturnType(ReturnType);

  for (const auto *Param : Function->parameters())
    Signature.addParameter(Param->getName(), getFragmentsForParam(Param));

  return Signature;
}

} // namespace extractapi
} // namespace clang

#endif // LLVM_CLANG_EXTRACTAPI_DECLARATION_FRAGMENTS_H
