//===-- IncludeFixer.h - Include inserter -----------------------*- 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
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_TOOLS_EXTRA_INCLUDE_FIXER_INCLUDEFIXER_H
#define LLVM_CLANG_TOOLS_EXTRA_INCLUDE_FIXER_INCLUDEFIXER_H

#include "IncludeFixerContext.h"
#include "SymbolIndexManager.h"
#include "clang/Format/Format.h"
#include "clang/Sema/ExternalSemaSource.h"
#include "clang/Tooling/Core/Replacement.h"
#include "clang/Tooling/Tooling.h"
#include <memory>
#include <vector>

namespace clang {

class CompilerInvocation;
class DiagnosticConsumer;
class FileManager;
class PCHContainerOperations;

namespace include_fixer {

class IncludeFixerActionFactory : public clang::tooling::ToolAction {
public:
  /// \param SymbolIndexMgr A source for matching symbols to header files.
  /// \param Contexts The contexts for the symbols being queried.
  /// \param StyleName Fallback style for reformatting.
  /// \param MinimizeIncludePaths whether inserted include paths are optimized.
  IncludeFixerActionFactory(SymbolIndexManager &SymbolIndexMgr,
                            std::vector<IncludeFixerContext> &Contexts,
                            StringRef StyleName,
                            bool MinimizeIncludePaths = true);

  ~IncludeFixerActionFactory() override;

  bool
  runInvocation(std::shared_ptr<clang::CompilerInvocation> Invocation,
                clang::FileManager *Files,
                std::shared_ptr<clang::PCHContainerOperations> PCHContainerOps,
                clang::DiagnosticConsumer *Diagnostics) override;

private:
  /// The client to use to find cross-references.
  SymbolIndexManager &SymbolIndexMgr;

  /// Multiple contexts for files being processed.
  std::vector<IncludeFixerContext> &Contexts;

  /// Whether inserted include paths should be optimized.
  bool MinimizeIncludePaths;

  /// The fallback format style for formatting after insertion if no
  /// clang-format config file was found.
  std::string FallbackStyle;
};

/// Create replacements, which are generated by clang-format, for the
/// missing header and missing qualifiers insertions. The function uses the
/// first header for insertion.
///
/// \param Code The source code.
/// \param Context The context which contains all information for creating
/// clang-include-fixer replacements.
/// \param Style clang-format style being used.
/// \param AddQualifiers  Whether we should add qualifiers to all instances of
/// an unidentified symbol.
///
/// \return Formatted replacements for inserting, sorting headers and adding
/// qualifiers on success; otherwise, an llvm::Error carrying llvm::StringError
/// is returned.
llvm::Expected<tooling::Replacements> createIncludeFixerReplacements(
    StringRef Code, const IncludeFixerContext &Context,
    const format::FormatStyle &Style = format::getLLVMStyle(),
    bool AddQualifiers = true);

/// Handles callbacks from sema, does the include lookup and turns it into an
/// IncludeFixerContext.
class IncludeFixerSemaSource : public clang::ExternalSemaSource {
public:
  explicit IncludeFixerSemaSource(SymbolIndexManager &SymbolIndexMgr,
                                  bool MinimizeIncludePaths,
                                  bool GenerateDiagnostics)
      : SymbolIndexMgr(SymbolIndexMgr),
        MinimizeIncludePaths(MinimizeIncludePaths),
        GenerateDiagnostics(GenerateDiagnostics) {}

  void setCompilerInstance(CompilerInstance *CI) { this->CI = CI; }
  void setFilePath(StringRef FilePath) {
    this->FilePath = std::string(FilePath);
  }

  /// Callback for incomplete types. If we encounter a forward declaration we
  /// have the fully qualified name ready. Just query that.
  bool MaybeDiagnoseMissingCompleteType(clang::SourceLocation Loc,
                                        clang::QualType T) override;

  /// Callback for unknown identifiers. Try to piece together as much
  /// qualification as we can get and do a query.
  clang::TypoCorrection CorrectTypo(const DeclarationNameInfo &Typo,
                                    int LookupKind, Scope *S, CXXScopeSpec *SS,
                                    CorrectionCandidateCallback &CCC,
                                    DeclContext *MemberContext,
                                    bool EnteringContext,
                                    const ObjCObjectPointerType *OPT) override;

  /// Get the minimal include for a given path.
  std::string minimizeInclude(StringRef Include,
                              const clang::SourceManager &SourceManager,
                              clang::HeaderSearch &HeaderSearch) const;

  /// Get the include fixer context for the queried symbol.
  IncludeFixerContext getIncludeFixerContext(
      const clang::SourceManager &SourceManager,
      clang::HeaderSearch &HeaderSearch,
      ArrayRef<find_all_symbols::SymbolInfo> MatchedSymbols) const;

  /// Get the global matched symbols.
  ArrayRef<find_all_symbols::SymbolInfo> getMatchedSymbols() const {
    return MatchedSymbols;
  }

private:
  /// Query the database for a given identifier.
  std::vector<find_all_symbols::SymbolInfo>
  query(StringRef Query, StringRef ScopedQualifiers, tooling::Range Range);

  CompilerInstance *CI;

  /// The client to use to find cross-references.
  SymbolIndexManager &SymbolIndexMgr;

  /// The information of the symbols being queried.
  std::vector<IncludeFixerContext::QuerySymbolInfo> QuerySymbolInfos;

  /// All symbol candidates which match QuerySymbol. We only include the first
  /// discovered identifier to avoid getting caught in results from error
  /// recovery.
  std::vector<find_all_symbols::SymbolInfo> MatchedSymbols;

  /// The file path to the file being processed.
  std::string FilePath;

  /// Whether we should use the smallest possible include path.
  bool MinimizeIncludePaths = true;

  /// Whether we should generate diagnostics with fixits for missing symbols.
  bool GenerateDiagnostics = false;
};
} // namespace include_fixer
} // namespace clang

#endif // LLVM_CLANG_TOOLS_EXTRA_INCLUDE_FIXER_INCLUDEFIXER_H
