//===- ClangSyntaxEmitter.cpp - Generate clang Syntax Tree nodes ----------===//
//
//                     The LLVM Compiler Infrastructure
//
// 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
//
//===----------------------------------------------------------------------===//
//
// These backends consume the definitions of Syntax Tree nodes.
// See clang/include/clang/Tooling/Syntax/{Syntax,Nodes}.td
//
// The -gen-clang-syntax-node-list backend produces a .inc with macro calls
//   NODE(Kind, BaseKind)
//   ABSTRACT_NODE(Type, Base, FirstKind, LastKind)
// similar to those for AST nodes such as AST/DeclNodes.inc.
//
// The -gen-clang-syntax-node-classes backend produces definitions for the
// syntax::Node subclasses (except those marked as External).
//
// In future, another backend will encode the structure of the various node
// types in tables so their invariants can be checked and enforced.
//
//===----------------------------------------------------------------------===//
#include "TableGenBackends.h"

#include <deque>

#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/TableGen/Record.h"
#include "llvm/TableGen/TableGenBackend.h"

using namespace llvm;

namespace {

// The class hierarchy of Node types.
// We assemble this in order to be able to define the NodeKind enum in a
// stable and useful way, where abstract Node subclasses correspond to ranges.
class Hierarchy {
public:
  Hierarchy(const RecordKeeper &Records) {
    for (const Record *T : Records.getAllDerivedDefinitions("NodeType"))
      add(T);
    for (const Record *Derived : Records.getAllDerivedDefinitions("NodeType"))
      if (const Record *Base = Derived->getValueAsOptionalDef("base"))
        link(Derived, Base);
    for (NodeType &N : AllTypes) {
      sort(N.Derived, [](const NodeType *L, const NodeType *R) {
        return L->Rec->getName() < R->Rec->getName();
      });
      // Alternatives nodes must have subclasses, External nodes may do.
      assert(N.Rec->isSubClassOf("Alternatives") ||
             N.Rec->isSubClassOf("External") || N.Derived.empty());
      assert(!N.Rec->isSubClassOf("Alternatives") || !N.Derived.empty());
    }
  }

  struct NodeType {
    const Record *Rec = nullptr;
    const NodeType *Base = nullptr;
    std::vector<const NodeType *> Derived;
    StringRef name() const { return Rec->getName(); }
  };

  NodeType &get(StringRef Name = "Node") {
    auto NI = ByName.find(Name);
    assert(NI != ByName.end() && "no such node");
    return *NI->second;
  }

  // Traverse the hierarchy in pre-order (base classes before derived).
  void visit(function_ref<void(const NodeType &)> CB,
             const NodeType *Start = nullptr) {
    if (Start == nullptr)
      Start = &get();
    CB(*Start);
    for (const NodeType *D : Start->Derived)
      visit(CB, D);
  }

private:
  void add(const Record *R) {
    AllTypes.emplace_back();
    AllTypes.back().Rec = R;
    bool Inserted = ByName.try_emplace(R->getName(), &AllTypes.back()).second;
    assert(Inserted && "Duplicate node name");
    (void)Inserted;
  }

  void link(const Record *Derived, const Record *Base) {
    auto &CN = get(Derived->getName()), &PN = get(Base->getName());
    assert(CN.Base == nullptr && "setting base twice");
    PN.Derived.push_back(&CN);
    CN.Base = &PN;
  }

  std::deque<NodeType> AllTypes;
  DenseMap<StringRef, NodeType *> ByName;
};

const Hierarchy::NodeType &firstConcrete(const Hierarchy::NodeType &N) {
  return N.Derived.empty() ? N : firstConcrete(*N.Derived.front());
}
const Hierarchy::NodeType &lastConcrete(const Hierarchy::NodeType &N) {
  return N.Derived.empty() ? N : lastConcrete(*N.Derived.back());
}

struct SyntaxConstraint {
  SyntaxConstraint(const Record &R) {
    if (R.isSubClassOf("Optional")) {
      *this = SyntaxConstraint(*R.getValueAsDef("inner"));
    } else if (R.isSubClassOf("AnyToken")) {
      NodeType = "Leaf";
    } else if (R.isSubClassOf("NodeType")) {
      NodeType = R.getName().str();
    } else {
      assert(false && "Unhandled Syntax kind");
    }
  }

  std::string NodeType;
  // optional and leaf types also go here, once we want to use them.
};

} // namespace

void clang::EmitClangSyntaxNodeList(const RecordKeeper &Records,
                                    raw_ostream &OS) {
  emitSourceFileHeader("Syntax tree node list", OS, Records);
  Hierarchy H(Records);
  OS << R"cpp(
#ifndef NODE
#define NODE(Kind, Base)
#endif

#ifndef CONCRETE_NODE
#define CONCRETE_NODE(Kind, Base) NODE(Kind, Base)
#endif

#ifndef ABSTRACT_NODE
#define ABSTRACT_NODE(Kind, Base, First, Last) NODE(Kind, Base)
#endif

)cpp";
  H.visit([&](const Hierarchy::NodeType &N) {
    // Don't emit ABSTRACT_NODE for node itself, which has no parent.
    if (N.Base == nullptr)
      return;
    if (N.Derived.empty())
      OS << formatv("CONCRETE_NODE({0},{1})\n", N.name(), N.Base->name());
    else
      OS << formatv("ABSTRACT_NODE({0},{1},{2},{3})\n", N.name(),
                    N.Base->name(), firstConcrete(N).name(),
                    lastConcrete(N).name());
  });
  OS << R"cpp(
#undef NODE
#undef CONCRETE_NODE
#undef ABSTRACT_NODE
)cpp";
}

// Format a documentation string as a C++ comment.
// Trims leading whitespace handling since comments come from a TableGen file:
//    documentation = [{
//      This is a widget. Example:
//        widget.explode()
//    }];
// and should be formatted as:
//    /// This is a widget. Example:
//    ///   widget.explode()
// Leading and trailing whitespace lines are stripped.
// The indentation of the first line is stripped from all lines.
static void printDoc(StringRef Doc, raw_ostream &OS) {
  Doc = Doc.rtrim();
  StringRef Line;
  while (Line.trim().empty() && !Doc.empty())
    std::tie(Line, Doc) = Doc.split('\n');
  StringRef Indent = Line.take_while(isSpace);
  for (; !Line.empty() || !Doc.empty(); std::tie(Line, Doc) = Doc.split('\n')) {
    Line.consume_front(Indent);
    OS << "/// " << Line << "\n";
  }
}

void clang::EmitClangSyntaxNodeClasses(const RecordKeeper &Records,
                                       raw_ostream &OS) {
  emitSourceFileHeader("Syntax tree node list", OS, Records);
  Hierarchy H(Records);

  OS << "\n// Forward-declare node types so we don't have to carefully "
        "sequence definitions.\n";
  H.visit([&](const Hierarchy::NodeType &N) {
    OS << "class " << N.name() << ";\n";
  });

  OS << "\n// Node definitions\n\n";
  H.visit([&](const Hierarchy::NodeType &N) {
    if (N.Rec->isSubClassOf("External"))
      return;
    printDoc(N.Rec->getValueAsString("documentation"), OS);
    OS << formatv("class {0}{1} : public {2} {{\n", N.name(),
                  N.Derived.empty() ? " final" : "", N.Base->name());

    // Constructor.
    if (N.Derived.empty())
      OS << formatv("public:\n  {0}() : {1}(NodeKind::{0}) {{}\n", N.name(),
                    N.Base->name());
    else
      OS << formatv("protected:\n  {0}(NodeKind K) : {1}(K) {{}\npublic:\n",
                    N.name(), N.Base->name());

    if (N.Rec->isSubClassOf("Sequence")) {
      // Getters for sequence elements.
      for (const auto &C : N.Rec->getValueAsListOfDefs("children")) {
        assert(C->isSubClassOf("Role"));
        StringRef Role = C->getValueAsString("role");
        SyntaxConstraint Constraint(*C->getValueAsDef("syntax"));
        for (const char *Const : {"", "const "})
          OS << formatv(
              "  {2}{1} *get{0}() {2} {{\n"
              "    return llvm::cast_or_null<{1}>(findChild(NodeRole::{0}));\n"
              "  }\n",
              Role, Constraint.NodeType, Const);
      }
    }

    // classof. FIXME: move definition inline once ~all nodes are generated.
    OS << "  static bool classof(const Node *N);\n";

    OS << "};\n\n";
  });
}
