//===--- FixItRewriter.cpp - Fix-It Rewriter Diagnostic Client --*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This is a diagnostic client adaptor that performs rewrites as
// suggested by code modification hints attached to diagnostics. It
// then forwards any diagnostics to the adapted diagnostic client.
//
//===----------------------------------------------------------------------===//

#include "clang/Frontend/FixItRewriter.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Frontend/FrontendDiagnostic.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/System/Path.h"
#include "llvm/ADT/OwningPtr.h"
#include <cstdio>

using namespace clang;

FixItRewriter::FixItRewriter(Diagnostic &Diags, SourceManager &SourceMgr,
                             const LangOptions &LangOpts)
  : Diags(Diags), Rewrite(SourceMgr, LangOpts), NumFailures(0) {
  Client = Diags.getClient();
  Diags.setClient(this);
}

FixItRewriter::~FixItRewriter() {
  Diags.setClient(Client);
}

bool FixItRewriter::WriteFixedFile(const std::string &InFileName,
                                   const std::string &OutFileName) {
  if (NumFailures > 0) {
    Diag(FullSourceLoc(), diag::warn_fixit_no_changes);
    return true;
  }

  llvm::OwningPtr<llvm::raw_ostream> OwnedStream;
  llvm::raw_ostream *OutFile;
  if (!OutFileName.empty()) {
    std::string Err;
    OutFile = new llvm::raw_fd_ostream(OutFileName.c_str(), Err,
                                       llvm::raw_fd_ostream::F_Binary);
    OwnedStream.reset(OutFile);
  } else if (InFileName == "-") {
    OutFile = &llvm::outs();
  } else {
    llvm::sys::Path Path(InFileName);
    std::string Suffix = Path.getSuffix();
    Path.eraseSuffix();
    Path.appendSuffix("fixit." + Suffix);
    std::string Err;
    OutFile = new llvm::raw_fd_ostream(Path.c_str(), Err,
                                       llvm::raw_fd_ostream::F_Binary);
    OwnedStream.reset(OutFile);
  }

  FileID MainFileID = Rewrite.getSourceMgr().getMainFileID();
  if (const RewriteBuffer *RewriteBuf =
        Rewrite.getRewriteBufferFor(MainFileID)) {
    *OutFile << std::string(RewriteBuf->begin(), RewriteBuf->end());
  } else {
    std::fprintf(stderr, "Main file is unchanged\n");
  }
  OutFile->flush();

  return false;
}

bool FixItRewriter::IncludeInDiagnosticCounts() const {
  return Client? Client->IncludeInDiagnosticCounts() : true;
}

void FixItRewriter::HandleDiagnostic(Diagnostic::Level DiagLevel,
                                     const DiagnosticInfo &Info) {
  Client->HandleDiagnostic(DiagLevel, Info);

  // Skip over any diagnostics that are ignored.
  if (DiagLevel == Diagnostic::Ignored)
    return;

  if (!FixItLocations.empty()) {
    // The user has specified the locations where we should perform
    // the various fix-it modifications.

    // If this diagnostic does not have any code modifications,
    // completely ignore it, even if it's an error: fix-it locations
    // are meant to perform specific fix-ups even in the presence of
    // other errors.
    if (Info.getNumCodeModificationHints() == 0)
      return;

    // See if the location of the error is one that matches what the
    // user requested.
    bool AcceptableLocation = false;
    const FileEntry *File
      = Rewrite.getSourceMgr().getFileEntryForID(
                                            Info.getLocation().getFileID());
    unsigned Line = Info.getLocation().getSpellingLineNumber();
    unsigned Column = Info.getLocation().getSpellingColumnNumber();
    for (llvm::SmallVector<RequestedSourceLocation, 4>::iterator
           Loc = FixItLocations.begin(), LocEnd = FixItLocations.end();
         Loc != LocEnd; ++Loc) {
      if (Loc->File == File && Loc->Line == Line && Loc->Column == Column) {
        AcceptableLocation = true;
        break;
      }
    }

    if (!AcceptableLocation)
      return;
  }

  // Make sure that we can perform all of the modifications we
  // in this diagnostic.
  bool CanRewrite = Info.getNumCodeModificationHints() > 0;
  for (unsigned Idx = 0, Last = Info.getNumCodeModificationHints();
       Idx < Last; ++Idx) {
    const CodeModificationHint &Hint = Info.getCodeModificationHint(Idx);
    if (Hint.RemoveRange.isValid() &&
        Rewrite.getRangeSize(Hint.RemoveRange) == -1) {
      CanRewrite = false;
      break;
    }

    if (Hint.InsertionLoc.isValid() &&
        !Rewrite.isRewritable(Hint.InsertionLoc)) {
      CanRewrite = false;
      break;
    }
  }

  if (!CanRewrite) {
    if (Info.getNumCodeModificationHints() > 0)
      Diag(Info.getLocation(), diag::note_fixit_in_macro);

    // If this was an error, refuse to perform any rewriting.
    if (DiagLevel == Diagnostic::Error || DiagLevel == Diagnostic::Fatal) {
      if (++NumFailures == 1)
        Diag(Info.getLocation(), diag::note_fixit_unfixed_error);
    }
    return;
  }

  bool Failed = false;
  for (unsigned Idx = 0, Last = Info.getNumCodeModificationHints();
       Idx < Last; ++Idx) {
    const CodeModificationHint &Hint = Info.getCodeModificationHint(Idx);
    if (!Hint.RemoveRange.isValid()) {
      // We're adding code.
      if (Rewrite.InsertTextBefore(Hint.InsertionLoc, Hint.CodeToInsert))
        Failed = true;
      continue;
    }

    if (Hint.CodeToInsert.empty()) {
      // We're removing code.
      if (Rewrite.RemoveText(Hint.RemoveRange.getBegin(),
                             Rewrite.getRangeSize(Hint.RemoveRange)))
        Failed = true;
      continue;
    }

    // We're replacing code.
    if (Rewrite.ReplaceText(Hint.RemoveRange.getBegin(),
                            Rewrite.getRangeSize(Hint.RemoveRange),
                            Hint.CodeToInsert))
      Failed = true;
  }

  if (Failed) {
    ++NumFailures;
    Diag(Info.getLocation(), diag::note_fixit_failed);
    return;
  }

  Diag(Info.getLocation(), diag::note_fixit_applied);
}

/// \brief Emit a diagnostic via the adapted diagnostic client.
void FixItRewriter::Diag(FullSourceLoc Loc, unsigned DiagID) {
  // When producing this diagnostic, we temporarily bypass ourselves,
  // clear out any current diagnostic, and let the downstream client
  // format the diagnostic.
  Diags.setClient(Client);
  Diags.Clear();
  Diags.Report(Loc, DiagID);
  Diags.setClient(this);
}
