// Part of the Crubit project, under the Apache License v2.0 with LLVM
// Exceptions. See /LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

#include "nullability/inference/replace_macros.h"

#include <cassert>
#include <string_view>

#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Lex/MacroInfo.h"
#include "clang/Lex/PPCallbacks.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Path.h"

namespace clang::tidy::nullability {
namespace {

// Prefix for the names of our copies of replaced macros.
//
// Used to identify whether a defined macro is itself a copy and to
// set each copy macro's definition equal to the pre-replacement definition of
// the macro it copies.
inline constexpr std::string_view CopyPrefix = "__clang_tidy_nullability_";
}  // namespace

void ReplaceMacrosCallbacks::FileChanged(SourceLocation Loc,
                                         FileChangeReason Reason,
                                         SrcMgr::CharacteristicKind FileType,
                                         FileID PrevFID) {
  if (State == State::FinishedReplacementFile) return;
  if (State == State::InReplacementFile && Reason == PPCallbacks::ExitFile) {
    State = State::FinishedReplacementFile;
    return;
  }

  if (Reason != PPCallbacks::EnterFile) return;

  auto FileName = PP.getSourceManager().getFilename(Loc);
  if (llvm::sys::path::remove_leading_dotslash(FileName) ==
      ReplacementMacrosHeaderFileName) {
    State = State::InReplacementFile;
  }
}

void ReplaceMacrosCallbacks::MacroDefined(const clang::Token &MacroNameTok,
                                          const clang::MacroDirective *MD) {
  auto *IIForCurrentMacro = MacroNameTok.getIdentifierInfo();
  assert(IIForCurrentMacro);

  if (State == State::InReplacementFile) {
    // The only macros in this file are the replacements, the copies of original
    // definitions, and the header guard.
    if (!IIForCurrentMacro->getName().starts_with(CopyPrefix)) {
      // Replacements are seen before the original definitions, so cache the
      // replacements for lookup later when we see the originals.

      // Unnecessary for the header guard, but not a problem, so don't bother
      // filtering.
      Replacements.insert({IIForCurrentMacro, MD});
    }
    return;
  }

  if (auto It = Replacements.find(IIForCurrentMacro);
      It != Replacements.end()) {
    const clang::MacroDirective *ReplacementDef = It->second;

    IdentifierInfo *CopyII =
        PP.getIdentifierInfo((CopyPrefix + IIForCurrentMacro->getName()).str());

    // Replace the (empty) definition of the copy with the pre-replacement
    // definition for this macro.
    PP.appendDefMacroDirective(
        CopyII, const_cast<clang::MacroInfo *>(MD->getMacroInfo()),
        MD->getLocation());

    // Replace the definition of this to-be-replaced macro with the
    // definition from the replacement file.
    PP.appendDefMacroDirective(
        IIForCurrentMacro,
        const_cast<clang::MacroInfo *>(ReplacementDef->getMacroInfo()),
        ReplacementDef->getLocation());
  }
}

}  // namespace clang::tidy::nullability
