//===--- DumpAST.cpp ---------------------------------------------*- 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
//
//===----------------------------------------------------------------------===//
// Defines a few tweaks that expose AST and related information.
// Some of these are fairly clang-specific and hidden (e.g. textual AST dumps).
// Others are more generally useful (class layout) and are exposed by default.
//===----------------------------------------------------------------------===//
#include "XRefs.h"
#include "refactor/Tweak.h"
#include "clang/AST/ASTTypeTraits.h"
#include "clang/AST/Type.h"
#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/ScopedPrinter.h"
#include "llvm/Support/raw_ostream.h"

namespace clang {
namespace clangd {
namespace {

/// Dumps the AST of the selected node.
/// Input:
///   fcall("foo");
///   ^^^^^
/// Message:
///   CallExpr
///   |-DeclRefExpr fcall
///   `-StringLiteral "foo"
class DumpAST : public Tweak {
public:
  const char *id() const override final;

  bool prepare(const Selection &Inputs) override {
    for (auto N = Inputs.ASTSelection.commonAncestor(); N && !Node;
         N = N->Parent)
      if (dumpable(N->ASTNode))
        Node = N->ASTNode;
    return Node.hasValue();
  }
  Expected<Effect> apply(const Selection &Inputs) override;
  std::string title() const override {
    return std::string(
        llvm::formatv("Dump {0} AST", Node->getNodeKind().asStringRef()));
  }
  llvm::StringLiteral kind() const override { return CodeAction::INFO_KIND; }
  bool hidden() const override { return true; }

private:
  static bool dumpable(const DynTypedNode &N) {
    // Sadly not all node types can be dumped, and there's no API to check.
    // See DynTypedNode::dump().
    return N.get<Decl>() || N.get<Stmt>() || N.get<Type>();
  }

  llvm::Optional<DynTypedNode> Node;
};
REGISTER_TWEAK(DumpAST)

llvm::Expected<Tweak::Effect> DumpAST::apply(const Selection &Inputs) {
  std::string Str;
  llvm::raw_string_ostream OS(Str);
  Node->dump(OS, Inputs.AST->getASTContext());
  return Effect::showMessage(std::move(OS.str()));
}

/// Dumps the SelectionTree.
/// Input:
/// int fcall(int);
/// void foo() {
///   fcall(2 + 2);
///     ^^^^^
/// }
/// Message:
/// TranslationUnitDecl
///   FunctionDecl void foo()
///     CompoundStmt {}
///      .CallExpr fcall(2 + 2)
///        ImplicitCastExpr fcall
///         .DeclRefExpr fcall
///        BinaryOperator 2 + 2
///          *IntegerLiteral 2
class ShowSelectionTree : public Tweak {
public:
  const char *id() const override final;

  bool prepare(const Selection &Inputs) override { return true; }
  Expected<Effect> apply(const Selection &Inputs) override {
    return Effect::showMessage(llvm::to_string(Inputs.ASTSelection));
  }
  std::string title() const override { return "Show selection tree"; }
  llvm::StringLiteral kind() const override { return CodeAction::INFO_KIND; }
  bool hidden() const override { return true; }
};
REGISTER_TWEAK(ShowSelectionTree)

/// Dumps the symbol under the cursor.
/// Inputs:
/// void foo();
///      ^^^
/// Message:
///  foo -
///  {"containerName":null,"id":"CA2EBE44A1D76D2A","name":"foo","usr":"c:@F@foo#"}
class DumpSymbol : public Tweak {
  const char *id() const override final;
  bool prepare(const Selection &Inputs) override { return true; }
  Expected<Effect> apply(const Selection &Inputs) override {
    std::string Storage;
    llvm::raw_string_ostream Out(Storage);

    for (auto &Sym : getSymbolInfo(
             *Inputs.AST, sourceLocToPosition(Inputs.AST->getSourceManager(),
                                              Inputs.Cursor)))
      Out << Sym;
    return Effect::showMessage(Out.str());
  }
  std::string title() const override { return "Dump symbol under the cursor"; }
  llvm::StringLiteral kind() const override { return CodeAction::INFO_KIND; }
  bool hidden() const override { return true; }
};
REGISTER_TWEAK(DumpSymbol)

/// Shows the layout of the RecordDecl under the cursor.
/// Input:
/// struct X { int foo; };
/// ^^^^^^^^
/// Message:
///        0 | struct S
///        0 |   int foo
///          | [sizeof=4, dsize=4, align=4,
///          |  nvsize=4, nvalign=4]
class DumpRecordLayout : public Tweak {
public:
  const char *id() const override final;

  bool prepare(const Selection &Inputs) override {
    if (auto *Node = Inputs.ASTSelection.commonAncestor())
      if (auto *D = Node->ASTNode.get<Decl>())
        Record = dyn_cast<RecordDecl>(D);
    return Record && Record->isThisDeclarationADefinition() &&
           !Record->isDependentType();
  }
  Expected<Effect> apply(const Selection &Inputs) override {
    std::string Str;
    llvm::raw_string_ostream OS(Str);
    Inputs.AST->getASTContext().DumpRecordLayout(Record, OS);
    return Effect::showMessage(std::move(OS.str()));
  }
  std::string title() const override {
    return std::string(llvm::formatv(
        "Show {0} layout",
        TypeWithKeyword::getTagTypeKindName(Record->getTagKind())));
  }
  llvm::StringLiteral kind() const override { return CodeAction::INFO_KIND; }
  // FIXME: this is interesting to most users. However:
  //  - triggering is too broad (e.g. triggers on comments within a class)
  //  - showMessage has inconsistent UX (e.g. newlines are stripped in VSCode)
  //  - the output itself is a bit hard to decipher.
  bool hidden() const override { return true; }

private:
  const RecordDecl *Record = nullptr;
};
REGISTER_TWEAK(DumpRecordLayout)

} // namespace
} // namespace clangd
} // namespace clang
