//===--- QuoteTransform.cpp - Quote transformation ------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2019 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
// This file implements routines associated with the transformation used to
// desugar #quote(...) expressions.
//
//===----------------------------------------------------------------------===//

#include "TypeChecker.h"
#include "swift/AST/ASTVisitor.h"
#include "swift/AST/ParameterList.h"
#include "swift/AST/TypeVisitor.h"
#include "swift/AST/USRGeneration.h"

using namespace swift;

namespace {

class Breadcrumbs {
private:
  SmallVector<SourceRange, 16> locs;

public:
  template <typename T> void push(T quotee) {
    locs.push_back(quotee->getSourceRange());
  }

  void push(Type quotee) { locs.push_back(SourceRange()); }

  void pop() { locs.pop_back(); }

  SourceLoc getLoc() {
    for (auto loc : reversed(locs)) {
      if (loc.isValid()) {
        return loc.Start;
      }
    }
    return SourceLoc();
  }
};

class Breadcrumb {
private:
  Breadcrumbs &bcs;

public:
  template <typename T> Breadcrumb(Breadcrumbs &bcs, T quotee) : bcs(bcs) {
    bcs.push(quotee);
  }

  ~Breadcrumb() { bcs.pop(); }
};

class AbstractQuoter {
protected:
  TypeChecker &tc;
  ASTContext &ctx;
  Breadcrumbs &bcs;

  AbstractQuoter(TypeChecker &tc, Breadcrumbs &bcs)
      : tc(tc), ctx(tc.Context), bcs(bcs) {}

  Expr *quoteArray(ArrayRef<Expr *> quotedTrees) {
    auto arrayExpr =
        ArrayExpr::create(ctx, SourceLoc(), quotedTrees, {}, SourceLoc());
    arrayExpr->setImplicit();
    return arrayExpr;
  }

  Expr *quoteBool(bool val) {
    return new (ctx) BooleanLiteralExpr(val, SourceLoc(), /*Implicit=*/true);
  }

  Expr *quoteFloat(StringRef val) {
    return new (ctx) FloatLiteralExpr(val, SourceLoc(), /*Implicit=*/true);
  }

  Expr *quoteInt(StringRef val) {
    return new (ctx) IntegerLiteralExpr(val, SourceLoc(), /*Implicit=*/true);
  }

  Expr *quoteInt(unsigned val) {
    return IntegerLiteralExpr::createFromUnsigned(ctx, val);
  }

  Expr *quoteString(StringRef str) {
    return new (ctx) StringLiteralExpr(str, SourceLoc(), /*Implicit=*/true);
  }

  Expr *quoteSymbol(ValueDecl *decl) {
    if (decl) {
      auto usr = allocateString(
          [&](raw_ostream &os) { return ide::printDeclUSR(decl, os); });
      return usr.empty() ? unknownSymbol(decl) : quoteString(usr);
    } else {
      return unknownSymbol(decl);
    }
  }

  // TODO(TF-735): Implement ExpressibleByQuoteLiteral.
  Expr *makeQuote(const char *name, ArrayRef<Expr *> quotedSubnodes) {
    auto nodeInit = new (ctx) UnresolvedDeclRefExpr(
        ctx.getIdentifier(name), DeclRefKind::Ordinary, DeclNameLoc());
    return CallExpr::createImplicit(ctx, nodeInit, quotedSubnodes, {});
  }

  template <typename T> Expr *unknownName(T culprit) {
    diagnoseUnsupported(culprit);
    return makeQuote("Name", {quoteString("<?>"), quoteString(""),
                              makeQuote("UnknownTree", {})});
  }

  template <typename T> Expr *unknownTree(T culprit) {
    diagnoseUnsupported(culprit);
    return makeQuote("UnknownTree", {});
  }

  template <typename T> Expr *unknownSymbol(T culprit) {
    diagnoseUnsupported(culprit);
    return quoteString("");
  }

  template <typename T> void diagnoseUnsupported(T culprit) {
    if (culprit) {
      auto str =
          allocateString([&](raw_ostream &os) { return culprit->dump(os); });
      tc.diagnose(bcs.getLoc(), diag::quote_literal_unsupported_detailed, str);
    } else {
      tc.diagnose(bcs.getLoc(), diag::quote_literal_unsupported_brief);
    }
  }

private:
  StringRef allocateString(std::function<void(raw_ostream &)> printer) {
    llvm::SmallString<256> SS;
    llvm::raw_svector_ostream OS(SS);
    printer(OS);
    auto str = SS.str();
    if (str.empty()) {
      return str;
    } else {
      char *Mem = static_cast<char *>(ctx.Allocate(str.size(), 1));
      std::copy(str.begin(), str.end(), Mem);
      return StringRef(Mem, str.size());
    }
  }
};

class TypeQuoter : public TypeVisitor<TypeQuoter, Expr *>,
                   private AbstractQuoter {
public:
  TypeQuoter(TypeChecker &tc, Breadcrumbs &bcs) : AbstractQuoter(tc, bcs) {}

#define UNSUPPORTED_TYPE(TYPE)                                                 \
  Expr *visit##TYPE(TYPE *type) { return unknownTree(type); }

  Expr *visitAnyFunctionType(AnyFunctionType *type) {
    SmallVector<Expr *, 4> attrs;
    switch (type->getExtInfo().getDifferentiabilityKind()) {
    case DifferentiabilityKind::NonDifferentiable:
      break;
    case DifferentiabilityKind::Normal:
      attrs.push_back(makeQuote("Differentiable", {}));
      break;
    case DifferentiabilityKind::Linear:
      attrs.push_back(makeQuote("DifferentiableLinear", {}));
      break;
    }
    SmallVector<Type, 4> paramTypes;
    for (auto param : type->getParams()) {
      paramTypes.push_back(param.getOldType());
    }
    return makeQuote("FunctionType", {quoteArray(attrs), quoteTypes(paramTypes),
                                      quoteType(type->getResult())});
  }

  Expr *visitAnyMetatypeType(AnyMetatypeType *type) {
    return makeQuote("MetaType", {quoteType(type->getInstanceType())});
  }

  Expr *visitArraySliceType(ArraySliceType *type) {
    return makeQuote("ArrayType", {quoteType(type->getBaseType())});
  }

  Expr *visitBoundGenericType(BoundGenericType *type) {
    return makeQuote("SpecializedType", {quoteName(type->getDecl()),
                                         quoteTypes(type->getGenericArgs())});
  }

  // NOTE: From what I understand, these types are created later in the
  // pipeline so they cannot occur in code that is being quoted.
  UNSUPPORTED_TYPE(BuiltinType)

  Expr *visitDictionaryType(DictionaryType *type) {
    return makeQuote("DictionaryType", {quoteType(type->getKeyType()),
                                        quoteType(type->getValueType())});
  }

  // NOTE: From what I understand, these types don't occur in expressions
  // and only occur in declarations, so we aren't interested in them until
  // supporting other decls becomes a thing (#5).
  UNSUPPORTED_TYPE(DependentMemberType)
  UNSUPPORTED_TYPE(DynamicSelfType)

  // NOTE: If typechecking encountered errors, there's no point in quoting
  // anyway because none of that code will make it to runtime.
  UNSUPPORTED_TYPE(ErrorType)

  Expr *visitInOutType(InOutType *type) {
    return makeQuote("InoutType", {quoteType(type->getObjectType())});
  }

  Expr *visitLValueType(LValueType *type) {
    return makeQuote("LValueType", {quoteType(type->getObjectType())});
  }

  // NOTE: Since we ignore base in visitDotSyntaxBaseIgnoredExpr, from what
  // I understand, module types cannot reach type quoters.
  UNSUPPORTED_TYPE(ModuleType)

  Expr *visitNominalType(NominalType *type) {
    return quoteName(type->getDecl());
  }

  Expr *visitOptionalType(OptionalType *type) {
    return makeQuote("OptionalType", {quoteType(type->getBaseType())});
  }

  Expr *visitParenType(ParenType *type) {
    return quoteType(type->getUnderlyingType());
  }

  Expr *visitProtocolCompositionType(ProtocolCompositionType *type) {
    return makeQuote("AndType", {quoteTypes(type->getMembers())});
  }

  // NOTE: From what I understand, these types don't occur in expressions
  // and only occur in declarations, so we aren't interested in them until
  // supporting other decls becomes a thing (#5).
  UNSUPPORTED_TYPE(ReferenceStorageType)
  UNSUPPORTED_TYPE(SubstitutableType)

  // NOTE: From what I understand, these types are created later in the
  // pipeline so they cannot occur in code that is being quoted.
  UNSUPPORTED_TYPE(SILBlockStorageType)
  UNSUPPORTED_TYPE(SILBoxType)
  UNSUPPORTED_TYPE(SILFunctionType)
  UNSUPPORTED_TYPE(SILTokenType)

  Expr *visitTupleType(TupleType *type) {
    return makeQuote("TupleType", {quoteTypes(type->getElementTypes())});
  }

  Expr *visitTypeAliasType(TypeAliasType *type) {
    return quoteName(type->getDecl());
  }

  // NOTE: If typechecking encountered errors, there's no point in quoting
  // anyway because none of that code will make it to runtime.
  UNSUPPORTED_TYPE(TypeVariableType)
  UNSUPPORTED_TYPE(UnboundGenericType)
  UNSUPPORTED_TYPE(UnresolvedType)

#undef UNSUPPORTED_TYPE

private:
  Expr *quoteName(TypeDecl *decl) {
    return makeQuote(
        "TypeName",
        {quoteString(decl->getBaseName().userFacingName()), quoteSymbol(decl)});
  }

  Expr *quoteType(Type type) { return visit(type); }

  template <typename T> Expr *quoteTypes(T types) {
    SmallVector<Expr *, 4> quotedTypes;
    for (auto type : types) {
      quotedTypes.push_back(quoteType(type));
    }
    return quoteArray(quotedTypes);
  }
};

class ASTQuoter
    : public ASTVisitor<ASTQuoter, Expr *, Expr *, Expr *, void, void, void>,
      private AbstractQuoter {
  TypeQuoter typeQuoter;

public:
  ASTQuoter(TypeChecker &tc, Breadcrumbs &bcs)
      : AbstractQuoter(tc, bcs), typeQuoter(TypeQuoter(tc, bcs)) {}

#define UNSUPPORTED_EXPR(EXPR)                                                 \
  Expr *visit##EXPR(EXPR *expr) {                                              \
    Breadcrumb bc(bcs, expr);                                                  \
    return unknownTree(expr);                                                  \
  }

  Expr *visitArrayExpr(ArrayExpr *expr) {
    Breadcrumb bc(bcs, expr);
    return makeQuote("ArrayLiteral", {quoteExprs(expr->getElements()),
                                      quoteType(expr->getType())});
  }

  // NOTE: If typechecking encountered errors, there's no point in quoting
  // anyway because none of that code will make it to runtime.
  UNSUPPORTED_EXPR(ArrowExpr)

  Expr *visitAssignExpr(AssignExpr *expr) {
    Breadcrumb bc(bcs, expr);
    return makeQuote("Assign",
                     {quoteExpr(expr->getDest()), quoteExpr(expr->getSrc()),
                      quoteType(expr->getType())});
  }

  Expr *visitAutoClosureExpr(AutoClosureExpr *expr) {
    Breadcrumb bc(bcs, expr);
    return makeQuote("Closure",
                     {quoteParams(expr->getParameters()),
                      quoteBody(expr->getBody()), quoteType(expr->getType())});
  }

  Expr *visitBinaryExpr(BinaryExpr *expr) {
    Breadcrumb bc(bcs, expr);
    return makeQuote("Binary", {quoteExpr(expr->getArg()->getElements()[0]),
                                quoteExpr(expr->getFn()),
                                quoteExpr(expr->getArg()->getElements()[1]),
                                quoteType(expr->getType())});
  }

  // TODO(TF-723): Quote optional chaining.
  UNSUPPORTED_EXPR(BindOptionalExpr)

  Expr *visitBooleanLiteralExpr(BooleanLiteralExpr *expr) {
    Breadcrumb bc(bcs, expr);
    // TODO(TF-733): Figure out why this is not good enough.
    // auto type = expr->getType();
    auto type = ctx.getBoolDecl()->getDeclaredType();
    return makeQuote("BooleanLiteral",
                     {quoteBool(expr->getValue()), quoteType(type)});
  }

  Expr *visitCallerDefaultArgumentExpr(CallerDefaultArgumentExpr *expr) {
    Breadcrumb bc(bcs, expr);
    return quoteExpr(expr->getSubExpr());
  }

  Expr *visitCallExpr(CallExpr *expr) {
    Breadcrumb bc(bcs, expr);
    return makeQuote("Call",
                     {quoteExpr(expr->getFn()),
                      quoteLabels(expr->getArgumentLabels()),
                      quoteArgs(expr->getArg()), quoteType(expr->getType())});
  }

  Expr *visitCaptureListExpr(CaptureListExpr *expr) {
    Breadcrumb bc(bcs, expr);
    return quoteExpr(expr->getClosureBody());
  }

  Expr *visitClosureExpr(ClosureExpr *expr) {
    Breadcrumb bc(bcs, expr);
    return makeQuote("Closure",
                     {quoteParams(expr->getParameters()),
                      quoteBody(expr->getBody()), quoteType(expr->getType())});
  }

  // NOTE: There's no point in quoting IDE support artifacts.
  UNSUPPORTED_EXPR(CodeCompletionExpr)

  Expr *visitCoerceExpr(CoerceExpr *expr) {
    Breadcrumb bc(bcs, expr);
    return makeQuote(
        "As", {quoteExpr(expr->getSubExpr()), quoteType(expr->getType())});
  }

  Expr *visitConditionalCheckedCastExpr(ConditionalCheckedCastExpr *expr) {
    Breadcrumb bc(bcs, expr);
    return makeQuote("OptionalAs", {quoteExpr(expr->getSubExpr()),
                                    quoteType(expr->getCastTypeLoc().getType()),
                                    quoteType(expr->getType())});
  }

  Expr *visitConstructorRefCallExpr(ConstructorRefCallExpr *expr) {
    // TODO(TF-715): Allow @quoted on more decls.
    Breadcrumb bc(bcs, expr);
    if (auto ref = dyn_cast<DeclRefExpr>(expr->getFn())) {
      return makeQuote("Name", {quoteValue(ref->getDeclRef()),
                                quoteSymbol(ref->getDecl()),
                                quoteType(expr->getType())});
    } else {
      return unknownTree(expr);
    }
  }

  // NOTE: DeclQuoteExprs are only used in synthetic code generated for @quoted
  // declarations, and that cannot end up quoted.
  UNSUPPORTED_EXPR(DeclQuoteExpr)

  Expr *visitDeclRefExpr(DeclRefExpr *expr) {
    Breadcrumb bc(bcs, expr);
    auto quotedExpr = makeQuote("Name", {quoteValue(expr->getDeclRef()),
                                         quoteSymbol(expr->getDecl()),
                                         quoteType(expr->getType())});
    if (auto attr = expr->getDecl()->getAttrs().getAttribute<QuotedAttr>()) {
      auto quoteRef = new (ctx)
          DeclRefExpr(ConcreteDeclRef(attr->getQuoteDecl()), DeclNameLoc(),
                      /*Implicit=*/true);
      auto quoteCall = CallExpr::createImplicit(ctx, quoteRef, {}, {});
      auto &tc = TypeChecker::createForContext(ctx);
      auto type = tc.getTypeOfQuoteExpr(expr->getType(), expr->getLoc());
      return makeQuote("Unquote", {quotedExpr, quoteCall, quoteType(type)});
    } else {
      return quotedExpr;
    }
  }

  Expr *visitDefaultArgumentExpr(DefaultArgumentExpr *expr) {
    Breadcrumb bc(bcs, expr);
    // TODO(TF-741): Look up the corresponding decl.
    return makeQuote("Default", {quoteString(""), quoteType(expr->getType())});
  }

  Expr *visitDictionaryExpr(DictionaryExpr *expr) {
    Breadcrumb bc(bcs, expr);
    SmallVector<Expr *, 4> quotedExprs;
    for (auto element : expr->getElements()) {
      if (auto tuple = dyn_cast<TupleExpr>(element)) {
        for (auto element : tuple->getElements()) {
          quotedExprs.push_back(quoteExpr(element));
        }
      } else {
        Breadcrumb bc2(bcs, element);
        quotedExprs.push_back(unknownTree(element));
      }
    }
    return makeQuote("DictionaryLiteral",
                     {quoteArray(quotedExprs), quoteType(expr->getType())});
  }

  Expr *visitDiscardAssignmentExpr(DiscardAssignmentExpr *expr) {
    Breadcrumb bc(bcs, expr);
    return makeQuote("Wildcard", {});
  }

  // TODO(TF-723): Quote type(of:).
  UNSUPPORTED_EXPR(DynamicTypeExpr)

  Expr *visitDotSelfExpr(DotSelfExpr *expr) {
    Breadcrumb bc(bcs, expr);
    if (auto base = dyn_cast<TypeExpr>(expr->getSubExpr())) {
      // TODO(TF-730): Figure out why we can't simply do `base->getType()`.
      if (auto metaType = expr->getType()->getAs<MetatypeType>()) {
        return makeQuote("PostfixSelf", {quoteType(metaType->getInstanceType()),
                                         quoteType(expr->getType())});
      } else {
        return unknownTree(expr);
      }
    } else {
      return makeQuote("PostfixSelf", {quoteExpr(expr->getSubExpr()),
                                       quoteType(expr->getType())});
    }
  }

  Expr *visitDotSyntaxBaseIgnoredExpr(DotSyntaxBaseIgnoredExpr *expr) {
    Breadcrumb bc(bcs, expr);
    if (auto ref = dyn_cast<DeclRefExpr>(expr->getRHS())) {
      // TODO(TF-730): Figure out why this is not enough.
      auto baseType = expr->getLHS()->getType();
      auto refType = ref->getType();
      if (!baseType || !refType) {
        if (auto exprType = expr->getType()->getAs<FunctionType>()) {
          baseType = exprType->getParams()[0].getPlainType();
          refType = exprType->getResult();
        } else {
          return unknownTree(expr);
        }
      }

      auto quotedExpr =
          makeQuote("Name", {quoteValue(ref->getDeclRef()),
                             quoteSymbol(ref->getDecl()), quoteType(refType)});
      if (auto attr = ref->getDecl()->getAttrs().getAttribute<QuotedAttr>()) {
        auto quoteRef = new (ctx)
            DeclRefExpr(ConcreteDeclRef(attr->getQuoteDecl()), DeclNameLoc(),
                        /*Implicit=*/true);
        auto quoteBase = TypeExpr::createImplicit(baseType, ctx);
        auto quoteDot =
            new (ctx) DotSyntaxCallExpr(quoteRef, SourceLoc(), quoteBase);
        auto quoteCall = CallExpr::createImplicit(ctx, quoteDot, {}, {});
        auto &tc = TypeChecker::createForContext(ctx);
        auto type = tc.getTypeOfQuoteExpr(refType, ref->getLoc());
        return makeQuote("Unquote", {quotedExpr, quoteCall, quoteType(type)});
      } else {
        return quotedExpr;
      }
    } else {
      return unknownTree(expr);
    }
  }

  Expr *visitDotSyntaxCallExpr(DotSyntaxCallExpr *expr) {
    Breadcrumb bc(bcs, expr);
    if (auto ref = dyn_cast<DeclRefExpr>(expr->getFn())) {
      if (dyn_cast<TypeExpr>(expr->getBase())) {
        // TODO(TF-715): Allow @quoted on more decls.
        return makeQuote("Name", {quoteValue(ref->getDeclRef()),
                                  quoteSymbol(ref->getDecl()),
                                  quoteType(expr->getType())});
      } else {
        auto quotedExpr = makeQuote("Member", {quoteExpr(expr->getBase()),
                                               quoteValue(ref->getDeclRef()),
                                               quoteSymbol(ref->getDecl()),
                                               quoteType(expr->getType())});
        if (auto attr = ref->getDecl()->getAttrs().getAttribute<QuotedAttr>()) {
          auto quoteRef = new (ctx)
              DeclRefExpr(ConcreteDeclRef(attr->getQuoteDecl()), DeclNameLoc(),
                          /*Implicit=*/true);
          auto quoteBase =
              TypeExpr::createImplicit(expr->getBase()->getType(), ctx);
          auto quoteDot =
              new (ctx) DotSyntaxCallExpr(quoteRef, SourceLoc(), quoteBase);
          auto quoteCall = CallExpr::createImplicit(ctx, quoteDot, {}, {});
          auto &tc = TypeChecker::createForContext(ctx);
          auto type = tc.getTypeOfQuoteExpr(expr->getType(), expr->getLoc());
          return makeQuote("Unquote", {quotedExpr, quoteCall, quoteType(type)});
        } else {
          return quotedExpr;
        }
      }
    } else {
      return unknownTree(expr);
    }
  }

  // TODO(TF-723): Quote dynamic lookup exprs.
  UNSUPPORTED_EXPR(DynamicLookupExpr)

  // NOTE: There's no point in quoting IDE support artifacts.
  UNSUPPORTED_EXPR(EditorPlaceholderExpr)

  Expr *visitEnumIsCaseExpr(EnumIsCaseExpr *expr) {
    Breadcrumb bc(bcs, expr);
    return makeQuote("Is",
                     {quoteExpr(expr->getSubExpr()),
                      quoteType(expr->getEnumElement()->getInterfaceType()),
                      quoteType(expr->getType())});
  }

  // NOTE: If typechecking encountered errors, there's no point in quoting
  // anyway because none of that code will make it to runtime.
  UNSUPPORTED_EXPR(ErrorExpr)

  Expr *visitFloatLiteralExpr(FloatLiteralExpr *expr) {
    Breadcrumb bc(bcs, expr);
    return makeQuote("FloatLiteral", {quoteFloat(expr->getDigitsText()),
                                      quoteType(expr->getType())});
  }

  Expr *visitForcedCheckedCastExpr(ForcedCheckedCastExpr *expr) {
    Breadcrumb bc(bcs, expr);
    return makeQuote(
        "ForceAs", {quoteExpr(expr->getSubExpr()), quoteType(expr->getType())});
  }

  Expr *visitForceTryExpr(ForceTryExpr *expr) {
    Breadcrumb bc(bcs, expr);
    return makeQuote("ForceTry", {quoteExpr(expr->getSubExpr()),
                                  quoteType(expr->getType())});
  }

  Expr *visitForceValueExpr(ForceValueExpr *expr) {
    Breadcrumb bc(bcs, expr);
    return makeQuote(
        "Force", {quoteExpr(expr->getSubExpr()), quoteType(expr->getType())});
  }

  Expr *visitIfExpr(IfExpr *expr) {
    Breadcrumb bc(bcs, expr);
    return makeQuote("Ternary", {quoteExpr(expr->getCondExpr()),
                                 quoteExpr(expr->getThenExpr()),
                                 quoteExpr(expr->getElseExpr()),
                                 quoteType(expr->getType())});
  }

  Expr *visitImplicitConversionExpr(ImplicitConversionExpr *expr) {
    Breadcrumb bc(bcs, expr);
    return makeQuote("Conversion", {quoteExpr(expr->getSubExpr()),
                                    quoteType(expr->getType())});
  }

  Expr *visitInOutExpr(InOutExpr *expr) {
    Breadcrumb bc(bcs, expr);
    // NOTE: If this expression is implicit, `expr` stands for a conversion that
    // is sometimes emitted when inout parameters are used.
    // Otherwise, `expr` stands for an in-out expression `&foo`.
    if (expr->isImplicit()) {
      return makeQuote("Conversion", {quoteExpr(expr->getSubExpr()),
                                      quoteType(expr->getType())});
    } else {
      return makeQuote(
          "Inout", {quoteExpr(expr->getSubExpr()), quoteType(expr->getType())});
    }
  }

  Expr *visitIntegerLiteralExpr(IntegerLiteralExpr *expr) {
    Breadcrumb bc(bcs, expr);
    return makeQuote("IntegerLiteral", {quoteInt(expr->getDigitsText()),
                                        quoteType(expr->getType())});
  }

  Expr *
  visitInterpolatedStringLiteralExpr(InterpolatedStringLiteralExpr *expr) {
    Breadcrumb bc(bcs, expr);
    /// TODO(TF-723): Finish the implementation.
    return makeQuote("StringInterpolation", {quoteType(expr->getType())});
  }

  Expr *visitIsExpr(IsExpr *expr) {
    Breadcrumb bc(bcs, expr);
    return makeQuote("Is", {quoteExpr(expr->getSubExpr()),
                            quoteType(expr->getCastTypeLoc().getType()),
                            quoteType(expr->getType())});
  }

  // TODO(TF-723): Quote key paths.
  UNSUPPORTED_EXPR(KeyPathApplicationExpr)
  UNSUPPORTED_EXPR(KeyPathDotExpr)
  UNSUPPORTED_EXPR(KeyPathExpr)

  Expr *visitLazyInitializerExpr(LazyInitializerExpr *expr) {
    Breadcrumb bc(bcs, expr);
    return quoteExpr(expr->getSubExpr());
  }

  Expr *visitMagicIdentifierLiteralExpr(MagicIdentifierLiteralExpr *expr) {
    Breadcrumb bc(bcs, expr);
    StringRef kind;
    switch (expr->getKind()) {
    case MagicIdentifierLiteralExpr::File:
      kind = "file";
      break;
    case MagicIdentifierLiteralExpr::Line:
      kind = "line";
      break;
    case MagicIdentifierLiteralExpr::Column:
      kind = "column";
      break;
    case MagicIdentifierLiteralExpr::Function:
      kind = "function";
      break;
    case MagicIdentifierLiteralExpr::DSOHandle:
      kind = "dsohandle";
      break;
    }
    return makeQuote("MagicLiteral",
                     {quoteString(kind), quoteType(expr->getType())});
  }

  Expr *visitMakeTemporarilyEscapableExpr(MakeTemporarilyEscapableExpr *expr) {
    Breadcrumb bc(bcs, expr);
    return quoteExpr(expr->getSubExpr());
  }

  Expr *visitMemberRefExpr(MemberRefExpr *expr) {
    // TODO(TF-715): Allow @quoted on more decls.
    Breadcrumb bc(bcs, expr);
    if (dyn_cast<TypeExpr>(expr->getBase())) {
      return makeQuote("Name", {quoteValue(expr->getMember()),
                                quoteSymbol(expr->getMember().getDecl()),
                                quoteType(expr->getType())});
    } else {
      return makeQuote("Member", {quoteExpr(expr->getBase()),
                                  quoteValue(expr->getMember()),
                                  quoteSymbol(expr->getMember().getDecl()),
                                  quoteType(expr->getType())});
    }
  }

  Expr *visitNilLiteralExpr(NilLiteralExpr *expr) {
    Breadcrumb bc(bcs, expr);
    return makeQuote("NilLiteral", {quoteType(expr->getType())});
  }

  // TODO(TF-723): Quote #selector.
  UNSUPPORTED_EXPR(ObjCSelectorExpr)

  // TODO(TF-723): Quote playground literals.
  UNSUPPORTED_EXPR(ObjectLiteralExpr)

  UNSUPPORTED_EXPR(OneWayExpr)

  // NOTE: TapExpr nodes are handled during quoting of their parent nodes.
  // We don't have a directly equivalent node in our trees.
  UNSUPPORTED_EXPR(OpaqueValueExpr)

  Expr *visitOpenExistentialExpr(OpenExistentialExpr *expr) {
    Breadcrumb bc(bcs, expr);
    if (auto call = dyn_cast<CallExpr>(expr->getSubExpr())) {
      if (auto dot = dyn_cast<DotSyntaxCallExpr>(call->getFn())) {
        if (auto ref = dyn_cast<DeclRefExpr>(dot->getFn())) {
          auto member =
              makeQuote("Member", {quoteExpr(expr->getExistentialValue()),
                                   quoteValue(ref->getDeclRef()),
                                   quoteSymbol(ref->getDecl()),
                                   quoteType(dot->getType())});
          return makeQuote(
              "Call", {member, quoteLabels(call->getArgumentLabels()),
                       quoteArgs(call->getArg()), quoteType(call->getType())});
        }
      }
    }
    return unknownTree(expr);
  }

  // TODO(TF-723): Quote optional chaining.
  UNSUPPORTED_EXPR(OptionalEvaluationExpr)

  Expr *visitOptionalTryExpr(OptionalTryExpr *expr) {
    Breadcrumb bc(bcs, expr);
    return makeQuote("OptionalTry", {quoteExpr(expr->getSubExpr()),
                                     quoteType(expr->getType())});
  }

  // TODO(TF-724): Quote decls.
  UNSUPPORTED_EXPR(OtherConstructorDeclRefExpr)

  // NOTE: If typechecking encountered errors, there's no point in quoting
  // anyway because none of that code will make it to runtime.
  UNSUPPORTED_EXPR(OverloadedDeclRefExpr)

  Expr *visitParenExpr(ParenExpr *expr) {
    Breadcrumb bc(bcs, expr);
    return quoteExpr(expr->getSubExpr());
  }

  Expr *visitPrefixUnaryExpr(PrefixUnaryExpr *expr) {
    Breadcrumb bc(bcs, expr);
    return makeQuote("Prefix",
                     {quoteExpr(expr->getFn()), quoteExpr(expr->getArg()),
                      quoteType(expr->getType())});
  }

  Expr *visitPostfixUnaryExpr(PostfixUnaryExpr *expr) {
    Breadcrumb bc(bcs, expr);
    return makeQuote("Postfix",
                     {quoteExpr(expr->getFn()), quoteExpr(expr->getArg()),
                      quoteType(expr->getType())});
  }

  Expr *visitQuoteLiteralExpr(QuoteLiteralExpr *expr) {
    Breadcrumb bc(bcs, expr);
    return makeQuote(
        "Meta", {quoteExpr(expr->getSubExpr()), quoteType(expr->getType())});
  }

  // TODO(TF-724): Quote decls.
  UNSUPPORTED_EXPR(RebindSelfInConstructorExpr)

  // NOTE: If typechecking encountered errors, there's no point in quoting
  // anyway because none of that code will make it to runtime.
  UNSUPPORTED_EXPR(SequenceExpr)

  Expr *visitStringLiteralExpr(StringLiteralExpr *expr) {
    Breadcrumb bc(bcs, expr);
    // TODO(TF-733): Figure out why this is not good enough.
    // auto type = expr->getType();
    auto type = ctx.getStringDecl()->getDeclaredType();
    return makeQuote("StringLiteral",
                     {quoteString(expr->getValue()), quoteType(type)});
  }

  Expr *visitSubscriptExpr(SubscriptExpr *expr) {
    Breadcrumb bc(bcs, expr);
    return makeQuote("Subscript", {quoteExpr(expr->getBase()),
                                   quoteSymbol(expr->getMember().getDecl()),
                                   quoteLabels(expr->getArgumentLabels()),
                                   quoteExprs(expr->getIndex()),
                                   quoteType(expr->getType())});
  }

  Expr *visitSuperRefExpr(SuperRefExpr *expr) {
    Breadcrumb bc(bcs, expr);
    return makeQuote("Super", {quoteType(expr->getType())});
  }

  // NOTE: TapExpr nodes are handled during quoting of their parent nodes.
  // We don't have a directly equivalent node in our trees.
  UNSUPPORTED_EXPR(TapExpr)

  Expr *visitTryExpr(TryExpr *expr) {
    Breadcrumb bc(bcs, expr);
    return makeQuote(
        "Try", {quoteExpr(expr->getSubExpr()), quoteType(expr->getType())});
  }

  Expr *visitTupleElementExpr(TupleElementExpr *expr) {
    Breadcrumb bc(bcs, expr);
    return makeQuote("TupleElement", {quoteExpr(expr->getBase()),
                                      quoteInt(expr->getFieldNumber()),
                                      quoteType(expr->getType())});
  }

  Expr *visitTupleExpr(TupleExpr *expr) {
    Breadcrumb bc(bcs, expr);
    // TODO(TF-731): Figure out why expr->getType() is sometimes null.
    auto quotedType = expr->getType() ? quoteType(expr->getType())
                                      : makeQuote("UnknownTree", {});
    return makeQuote("Tuple", {quoteLabels(expr->getElementNames()),
                               quoteExprs(expr->getElements()), quotedType});
  }

  // NOTE: TypeExpr nodes are handled during quoting of their parent nodes.
  // We don't have a directly equivalent node in our trees.
  UNSUPPORTED_EXPR(TypeExpr)

  Expr *visitUnquoteExpr(UnquoteExpr *expr) {
    Breadcrumb bc(bcs, expr);
    auto value = new (ctx)
        UnresolvedDotExpr(expr->getSubExpr(), SourceLoc(),
                          ctx.getIdentifier("expression"), DeclNameLoc(),
                          /*Implicit=*/true);
    return makeQuote("Unquote", {quoteExpr(expr->getSubExpr()), value,
                                 quoteType(expr->getType())});
  }

  // NOTE: If typechecking encountered errors, there's no point in quoting
  // anyway because none of that code will make it to runtime.
  UNSUPPORTED_EXPR(UnresolvedDeclRefExpr)
  UNSUPPORTED_EXPR(UnresolvedDotExpr)
  UNSUPPORTED_EXPR(UnresolvedMemberExpr)
  UNSUPPORTED_EXPR(UnresolvedPatternExpr)
  UNSUPPORTED_EXPR(UnresolvedSpecializeExpr)

  Expr *visitVarargExpansionExpr(VarargExpansionExpr *expr) {
    Breadcrumb bc(bcs, expr);
    if (auto exprs = dyn_cast<ArrayExpr>(expr->getSubExpr())) {
      return makeQuote("Varargs", {quoteExprs(exprs->getElements()),
                                   quoteType(expr->getType())});
    } else {
      return unknownTree(expr);
    }
  }

#define UNSUPPORTED_STMT(STMT)                                                 \
  Expr *visit##STMT(STMT *stmt) {                                              \
    Breadcrumb bc(bcs, stmt);                                                  \
    return unknownTree(stmt);                                                  \
  }

  // NOTE: BraceStmts are supported within quoteBody but not in standalone form.
  UNSUPPORTED_STMT(BraceStmt)

  Expr *visitBreakStmt(BreakStmt *stmt) {
    Breadcrumb bc(bcs, stmt);
    return makeQuote("Break", {quoteLabel(stmt->getTargetName())});
  }

  // TODO(TF-714): Quote patterns and trees related to pattern matching.
  UNSUPPORTED_STMT(CaseStmt)

  // TODO(TF-714): Quote patterns and trees related to pattern matching.
  UNSUPPORTED_STMT(CatchStmt)

  Expr *visitContinueStmt(ContinueStmt *stmt) {
    Breadcrumb bc(bcs, stmt);
    return makeQuote("Continue", {quoteLabel(stmt->getTargetName())});
  }

  Expr *visitDeferStmt(DeferStmt *stmt) {
    Breadcrumb bc(bcs, stmt);
    return makeQuote("Defer", {quoteBody(stmt->getBodyAsWritten())});
  }

  // TODO(TF-714): Quote patterns and trees related to pattern matching.
  UNSUPPORTED_STMT(DoCatchStmt)

  Expr *visitDoStmt(DoStmt *stmt) {
    Breadcrumb bc(bcs, stmt);
    return makeQuote("Do", {quoteLabel(stmt->getLabelInfo().Name),
                            quoteBody(stmt->getBody())});
  }

  // TODO(TF-724): Quote decls.
  UNSUPPORTED_STMT(FailStmt)

  // TODO(TF-714): Quote patterns and trees related to pattern matching.
  UNSUPPORTED_STMT(FallthroughStmt)

  Expr *visitForEachStmt(ForEachStmt *stmt) {
    Breadcrumb bc(bcs, stmt);
    Expr *quotedName = nullptr;
    if (auto pat = dyn_cast<NamedPattern>(stmt->getPattern())) {
      Breadcrumb bc(bcs, pat);
      quotedName = quoteName(pat->getDecl());
    }
    if (!quotedName) {
      quotedName = unknownName(stmt);
    }
    return makeQuote("For", {quoteLabel(stmt->getLabelInfo().Name), quotedName,
                             quoteExpr(stmt->getSequence()),
                             quoteBody(stmt->getBody())});
  }

  Expr *visitGuardStmt(GuardStmt *stmt) {
    Breadcrumb bc(bcs, stmt);
    return makeQuote("Guard", {quoteCond(stmt), quoteBody(stmt->getBody())});
  }

  Expr *visitIfStmt(IfStmt *stmt) {
    Breadcrumb bc(bcs, stmt);
    auto quotedElse =
        stmt->getElseStmt() ? quoteBody(stmt->getElseStmt()) : quoteArray({});
    return makeQuote("If",
                     {quoteLabel(stmt->getLabelInfo().Name), quoteCond(stmt),
                      quoteBody(stmt->getThenStmt()), quotedElse});
  }

  // NOTE: PoundAssertStmt are supported within quoteBody but not in
  // standalone form.
  UNSUPPORTED_STMT(PoundAssertStmt)

  Expr *visitRepeatWhileStmt(RepeatWhileStmt *stmt) {
    Breadcrumb bc(bcs, stmt);
    return makeQuote("Repeat",
                     {quoteLabel(stmt->getLabelInfo().Name),
                      quoteBody(stmt->getBody()), quoteExpr(stmt->getCond())});
  }

  Expr *visitReturnStmt(ReturnStmt *stmt) {
    Breadcrumb bc(bcs, stmt);
    if (stmt->hasResult()) {
      return makeQuote("Return", {quoteExpr(stmt->getResult())});
    } else {
      auto emptyResult = TupleExpr::createEmpty(ctx, SourceLoc(), SourceLoc(),
                                                /*Implicit=*/true);
      return makeQuote("Return", {quoteExpr(emptyResult)});
    }
  }

  // TODO(TF-714): Quote patterns and trees related to pattern matching.
  UNSUPPORTED_STMT(SwitchStmt)

  Expr *visitThrowStmt(ThrowStmt *stmt) {
    Breadcrumb bc(bcs, stmt);
    return makeQuote("Throw", {quoteExpr(stmt->getSubExpr())});
  }

  Expr *visitWhileStmt(WhileStmt *stmt) {
    Breadcrumb bc(bcs, stmt);
    return makeQuote("While", {quoteLabel(stmt->getLabelInfo().Name),
                               quoteCond(stmt), quoteBody(stmt->getBody())});
  }

  // NOTE: Doesn't look like this is an official feature so we won't be
  // supporting it for now.
  UNSUPPORTED_STMT(YieldStmt)

#undef UNSUPPORTED_STMT

#define UNSUPPORTED_DECL(DECL)                                                 \
  Expr *visit##DECL(DECL *decl) {                                              \
    Breadcrumb bc(bcs, decl);                                                  \
    return unknownTree(decl);                                                  \
  }

  // TODO(TF-724): Quote decls.
  UNSUPPORTED_DECL(AccessorDecl)
  UNSUPPORTED_DECL(AssociatedTypeDecl)
  UNSUPPORTED_DECL(ConstructorDecl)
  UNSUPPORTED_DECL(ClassDecl)
  UNSUPPORTED_DECL(DestructorDecl)
  UNSUPPORTED_DECL(EnumCaseDecl)
  UNSUPPORTED_DECL(EnumDecl)
  UNSUPPORTED_DECL(EnumElementDecl)
  UNSUPPORTED_DECL(ExtensionDecl)

  Expr *visitFuncDecl(FuncDecl *decl) {
    return makeQuote("Function",
                     {quoteName(decl), quoteParams(decl->getParameters()),
                      quoteBody(decl->getBody())});
  }

  // TODO(TF-724): Quote decls.
  UNSUPPORTED_DECL(GenericTypeParamDecl)

  // NOTE: Doesn't have a representation in quotes.
  // We simply take active elements and use them instead of this decl.
  UNSUPPORTED_DECL(IfConfigDecl)

  // TODO(TF-724): Quote decls.
  UNSUPPORTED_DECL(ImportDecl)
  UNSUPPORTED_DECL(MissingMemberDecl)
  UNSUPPORTED_DECL(ModuleDecl)

  Expr *visitParamDecl(ParamDecl *decl) {
    Breadcrumb bc(bcs, decl);
    return makeQuote("Parameter",
                     {quoteLabel(decl->getArgumentName()), quoteName(decl)});
  }

  Expr *visitPatternBindingDecl(PatternBindingDecl *decl) {
    Breadcrumb bc(bcs, decl);
    if (auto var = decl->getSingleVar()) {
      Breadcrumb bc(bcs, var);
      if (var->isLet()) {
        return makeQuote("Let", {quoteName(var), quoteExpr(decl->getInit(0))});
      } else {
        return makeQuote("Var", {quoteName(var), quoteExpr(decl->getInit(0))});
      }
    } else {
      // TODO(TF-714): Quote patterns and trees related to pattern
      // matching.
      return unknownTree(decl);
    }
  }

  // NOTE: Doesn't have a representation in quotes since this language construct
  // belongs to the compilation stage that precedes quotes.
  UNSUPPORTED_DECL(PoundDiagnosticDecl)

  // TODO(TF-724): Quote decls.
  UNSUPPORTED_DECL(PrecedenceGroupDecl)
  UNSUPPORTED_DECL(ProtocolDecl)
  UNSUPPORTED_DECL(OpaqueTypeDecl)
  UNSUPPORTED_DECL(OperatorDecl)
  UNSUPPORTED_DECL(StructDecl)
  UNSUPPORTED_DECL(SubscriptDecl)
  UNSUPPORTED_DECL(TopLevelCodeDecl)
  UNSUPPORTED_DECL(TypeAliasDecl)
  UNSUPPORTED_DECL(VarDecl)

#undef UNSUPPORTED_DECL

private:
  Expr *quoteArgs(Expr *arg) {
    Breadcrumb bc(bcs, arg);
    if (auto args = dyn_cast<ParenExpr>(arg)) {
      return quoteExprs({args->getSubExpr()});
    } else if (auto args = dyn_cast<TupleExpr>(arg)) {
      return quoteExprs(args->getElements());
    } else {
      return quoteArray(unknownTree(arg));
    }
  }

  Expr *quoteBody(Stmt *stmt) {
    Breadcrumb bc(bcs, stmt);
    if (auto body = dyn_cast<BraceStmt>(stmt)) {
      SmallVector<Expr *, 4> quotedBody;
      std::function<void(ASTNode)> handleNode = [&](ASTNode node) {
        if (auto expr = node.dyn_cast<Expr *>()) {
          quotedBody.push_back(quoteExpr(expr));
          return;
        }
        if (auto stmt = node.dyn_cast<Stmt *>()) {
          if (isa<PoundAssertStmt>(stmt)) {
            return;
          }
          quotedBody.push_back(quoteStmt(stmt));
          return;
        }
        auto decl = node.get<Decl *>();
        if (auto poundIf = dyn_cast<IfConfigDecl>(decl)) {
          for (auto elem : poundIf->getActiveClauseElements()) {
            handleNode(elem);
          }
          return;
        }
        if (isa<PoundDiagnosticDecl>(decl)) {
          return;
        }
        if (isa<VarDecl>(decl)) {
          return;
        }
        quotedBody.push_back(quoteDecl(decl));
      };
      for (auto elem : body->getElements()) {
        handleNode(elem);
      }
      return quoteArray(quotedBody);
    } else {
      return quoteArray({quoteStmt(stmt)});
    }
  }

  template <typename T> Expr *quoteCond(T *stmt) {
    SmallVector<Expr *, 4> quotedCond;
    for (auto element : stmt->getCond()) {
      Breadcrumb bc(bcs, &element);
      Expr *quotedElement;
      switch (element.getKind()) {
      case StmtConditionElement::ConditionKind::CK_Boolean:
        quotedElement = quoteExpr(element.getBoolean());
        break;
      case StmtConditionElement::ConditionKind::CK_PatternBinding:
        // TODO(TF-714): Quote patterns and trees related to pattern
        // matching.
        quotedElement = unknownTree(stmt);
        break;
      case StmtConditionElement::ConditionKind::CK_Availability:
        // TODO(TF-723): Quote #available.
        quotedElement = unknownTree(stmt);
        break;
      }
      quotedCond.push_back(quotedElement);
    }
    return quoteArray(quotedCond);
  }

  Expr *quoteDecl(Decl *decl) { return visit(decl); }

  Expr *quoteExpr(Expr *expr) { return visit(expr); }

  Expr *quoteExprs(ArrayRef<Expr *> exprs) {
    SmallVector<Expr *, 4> quotedExprs;
    for (auto expr : exprs) {
      quotedExprs.push_back(quoteExpr(expr));
    }
    return quoteArray(quotedExprs);
  }

  Expr *quoteLabel(Identifier id) {
    if (id.empty()) {
      return quoteNil();
    } else {
      return quoteString(id.str());
    }
  }

  Expr *quoteLabels(ArrayRef<Identifier> ids) {
    SmallVector<Expr *, 4> quotedLabels;
    for (auto id : ids) {
      quotedLabels.push_back(quoteLabel(id));
    }
    return quoteArray(quotedLabels);
  }

  Expr *quoteName(ValueDecl *decl) {
    Type type;
    if (auto decl2 = dyn_cast<FuncDecl>(decl)) {
      SmallVector<AnyFunctionType::Param, 4> paramTypes;
      for (auto param : decl2->getParameters()->getArray()) {
        auto flags = ParameterTypeFlags();
        if (param->isInOut()) {
          flags = flags.withInOut(true);
        }
        auto paramType =
            AnyFunctionType::Param(param->getType(), Identifier(), flags);
        paramTypes.push_back(paramType);
      }
      auto retType = decl2->getBodyResultTypeLoc().getTypeRepr()
                         ? decl2->getBodyResultTypeLoc().getType()
                         : decl2->getResultInterfaceType();
      if (retType) {
        type = FunctionType::get(paramTypes, retType);
      }
    } else if (auto decl2 = dyn_cast<VarDecl>(decl)) {
      type = decl2->getType();
      if (auto decl2 = dyn_cast<ParamDecl>(decl)) {
        if (decl2->isInOut()) {
          type = InOutType::get(type);
        }
      }
    }
    Expr *quotedType = type ? quoteType(type) : unknownTree(decl);
    return makeQuote("Name", {quoteString(decl->getBaseName().userFacingName()),
                              quoteSymbol(decl), quotedType});
  }

  Expr *quoteNil() {
    return new (ctx) NilLiteralExpr(SourceLoc(), /*Implicit=*/true);
  }

  Expr *quoteParams(ParameterList *params) {
    SmallVector<Expr *, 4> quotedParams;
    for (auto param : params->getArray()) {
      quotedParams.push_back(quoteDecl(param));
    }
    return quoteArray(quotedParams);
  }

  Expr *quoteStmt(Stmt *stmt) { return visit(stmt); }

  Expr *quoteType(Type type) {
    return type ? typeQuoter.visit(type) : unknownTree(type);
  }

  Expr *quoteValue(ConcreteDeclRef ref) {
    // TODO(TF-740): Obtain value exactly as written by the programmer.
    // I'm currently not sure how to do that since DeclRefExpr doesn't have
    // a correct source range.
    if (auto ctor = dyn_cast<ConstructorDecl>(ref.getDecl())) {
      auto type = ctor->getResultInterfaceType();
      if (auto nomType = type->getAs<NominalType>()) {
        return quoteString(nomType->getDecl()->getBaseName().userFacingName());
      }
    }
    return quoteString(ref.getDecl()->getBaseName().userFacingName());
  }

  // TODO(TF-735): Implement ExpressibleByQuoteLiteral.
  Expr *makeQuote(const char *name, ArrayRef<Expr *> quotedSubnodes) {
    auto nodeInit = new (ctx) UnresolvedDeclRefExpr(
        ctx.getIdentifier(name), DeclRefKind::Ordinary, DeclNameLoc());
    return CallExpr::createImplicit(ctx, nodeInit, quotedSubnodes, {});
  }
};

} // end anonymous namespace

Expr *TypeChecker::quoteExpr(Expr *expr, DeclContext *dc) {
  assert(expr->getType());

  Breadcrumbs bcs;
  ASTQuoter astQuoter(*this, bcs);
  Expr *quotedExpr = astQuoter.visit(expr);
  if (!quotedExpr) {
    return nullptr;
  }

  auto quoteType = getTypeOfQuoteExpr(expr->getType(), expr->getLoc());
  if (!quoteType) {
    return nullptr;
  }

  auto quoteClassType = quoteType->getAs<BoundGenericClassType>();
  if (!quoteClassType) {
    return nullptr;
  }

  auto quoteRef =
      new (Context) UnresolvedDeclRefExpr(quoteClassType->getDecl()->getName(),
                                          DeclRefKind::Ordinary, DeclNameLoc());
  SmallVector<TypeLoc, 4> quoteTargs;
  for (auto targ : quoteClassType->getGenericArgs()) {
    auto targRepr = new (Context) FixedTypeRepr(targ, SourceLoc());
    quoteTargs.push_back(TypeLoc(targRepr));
  }
  auto quoteInit = UnresolvedSpecializeExpr::create(
      Context, quoteRef, SourceLoc(), quoteTargs, SourceLoc());
  quoteInit->setImplicit();
  Expr *quoteCall =
      CallExpr::createImplicit(Context, quoteInit, {quotedExpr}, {});

  // TODO(TF-727): Improve error reporting when quoting fails.
  if (!typeCheckExpression(quoteCall, dc)) {
    return nullptr;
  }

  // TODO(TF-734): Get to the bottom of why we need this workaround.
  if (auto call2 = dyn_cast<CallExpr>(quoteCall)) {
    if (auto init2 = dyn_cast<ConstructorRefCallExpr>(call2->getFn())) {
      init2->getBase()->setImplicit();
      return quoteCall;
    }
  }

  return nullptr;
}

Type TypeChecker::getTypeOfQuoteExpr(Type exprType, SourceLoc loc) {
  assert(exprType);
  if (!Context.getQuoteModule()) {
    diagnose(loc, diag::quote_literal_no_quote_module);
    return Type();
  }
  if (auto fnExprType = exprType->getAs<FunctionType>()) {
    auto n = fnExprType->getParams().size();
    auto quoteClass = Context.getFunctionQuoteDecl(n);
    if (!quoteClass) {
      diagnose(loc, diag::quote_literal_no_function_quote_class, n);
      return Type();
    }
    SmallVector<Type, 4> typeArgs;
    for (auto param : fnExprType->getParams()) {
      auto paramType = param.getPlainType();
      if (param.isInOut()) {
        paramType = paramType->wrapInPointer(PTK_UnsafeMutablePointer);
      }
      typeArgs.push_back(paramType);
    }
    typeArgs.push_back(fnExprType->getResult());
    return BoundGenericClassType::get(quoteClass, Type(), typeArgs);
  } else {
    auto quoteClass = Context.getQuoteDecl();
    if (!quoteClass) {
      diagnose(loc, diag::quote_literal_no_quote_class);
      return Type();
    }
    if (auto lvalueExprType = exprType->getAs<LValueType>()) {
      exprType = lvalueExprType->getObjectType();
    }
    return BoundGenericClassType::get(quoteClass, Type(), exprType);
  }
}

Type TypeChecker::getTypeOfUnquoteExpr(Type exprType, SourceLoc loc) {
  assert(exprType);
  if (auto genericType = exprType->getAs<BoundGenericClassType>()) {
    auto classDecl = genericType->getDecl();
    auto typeArgs = genericType->getGenericArgs();
    if (classDecl == Context.getQuoteDecl()) {
      return typeArgs[0];
    } else if (classDecl == Context.getFunctionQuoteDecl(typeArgs.size() - 1)) {
      SmallVector<AnyFunctionType::Param, 4> paramTypes;
      for (unsigned i = 0; i < typeArgs.size() - 1; ++i) {
        auto typeArg = typeArgs[i];
        auto flags = ParameterTypeFlags();
        if (auto genericTypeArg = typeArg->getAs<BoundGenericClassType>()) {
          if (genericTypeArg->getDecl() ==
              Context.getUnsafeMutablePointerDecl()) {
            flags = flags.withInOut(true);
          }
        }
        auto paramType = AnyFunctionType::Param(typeArg, Identifier(), flags);
        paramTypes.push_back(paramType);
      }
      return FunctionType::get(paramTypes, typeArgs[typeArgs.size() - 1]);
    } else {
      diagnose(loc, diag::unquote_wrong_type);
      return Type();
    }
  } else {
    diagnose(loc, diag::unquote_wrong_type);
    return Type();
  }
}

Expr *TypeChecker::quoteDecl(Decl *decl, DeclContext *dc) {
  Breadcrumbs bcs;
  ASTQuoter astQuoter(*this, bcs);
  Expr *quotedDecl = astQuoter.visit(decl);
  if (!quotedDecl) {
    return nullptr;
  }

  // TODO(TF-727): Improve error reporting when quoting fails.
  if (!typeCheckExpression(quotedDecl, dc)) {
    return nullptr;
  }

  return quotedDecl;
}

Type TypeChecker::getTypeOfQuoteDecl(SourceLoc loc) {
  if (!Context.getQuoteModule()) {
    diagnose(loc, diag::quote_literal_no_quote_module);
    return Type();
  }
  auto treeProto = Context.getTreeDecl();
  if (!treeProto) {
    diagnose(loc, diag::quote_literal_no_tree_proto);
    return Type();
  }
  return treeProto->getDeclaredType();
}
