//===--- ExpectedTypes.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
//
//===----------------------------------------------------------------------===//

#include "ExpectedTypes.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/Type.h"
#include "clang/Index/USRGeneration.h"
#include "clang/Sema/CodeCompleteConsumer.h"
#include "llvm/ADT/None.h"
#include "llvm/ADT/STLExtras.h"

namespace clang {
namespace clangd {
namespace {

static const Type *toEquivClass(ASTContext &Ctx, QualType T) {
  if (T.isNull() || T->isDependentType())
    return nullptr;
  // Drop references, we do not handle reference inits properly anyway.
  T = T.getCanonicalType().getNonReferenceType();
  // Numeric types are the simplest case.
  if (T->isBooleanType())
    return Ctx.BoolTy.getTypePtr();
  if (T->isIntegerType() && !T->isEnumeralType())
    return Ctx.IntTy.getTypePtr(); // All integers are equivalent.
  if (T->isFloatingType() && !T->isComplexType())
    return Ctx.FloatTy.getTypePtr(); // All floats are equivalent.

  // Do some simple transformations.
  if (T->isArrayType()) // Decay arrays to pointers.
    return Ctx.getPointerType(QualType(T->getArrayElementTypeNoTypeQual(), 0))
        .getTypePtr();
  // Drop the qualifiers and return the resulting type.
  // FIXME: also drop qualifiers from pointer types, e.g. 'const T* => T*'
  return T.getTypePtr();
}

static llvm::Optional<QualType>
typeOfCompletion(const CodeCompletionResult &R) {
  const NamedDecl *D = R.Declaration;
  // Templates do not have a type on their own, look at the templated decl.
  if (auto *Template = dyn_cast_or_null<TemplateDecl>(D))
    D = Template->getTemplatedDecl();
  auto *VD = dyn_cast_or_null<ValueDecl>(D);
  if (!VD)
    return llvm::None; // We handle only variables and functions below.
  auto T = VD->getType();
  if (T.isNull())
    return llvm::None;
  if (auto FuncT = T->getAs<FunctionType>()) {
    // Functions are a special case. They are completed as 'foo()' and we want
    // to match their return type rather than the function type itself.
    // FIXME(ibiryukov): in some cases, we might want to avoid completing `()`
    // after the function name, e.g. `std::cout << std::endl`.
    return FuncT->getReturnType();
  }
  return T;
}
} // namespace

llvm::Optional<OpaqueType> OpaqueType::encode(ASTContext &Ctx, QualType T) {
  if (T.isNull())
    return None;
  const Type *C = toEquivClass(Ctx, T);
  if (!C)
    return None;
  llvm::SmallString<128> Encoded;
  if (index::generateUSRForType(QualType(C, 0), Ctx, Encoded))
    return None;
  return OpaqueType(std::string(Encoded.str()));
}

OpaqueType::OpaqueType(std::string Data) : Data(std::move(Data)) {}

llvm::Optional<OpaqueType> OpaqueType::fromType(ASTContext &Ctx,
                                                QualType Type) {
  return encode(Ctx, Type);
}

llvm::Optional<OpaqueType>
OpaqueType::fromCompletionResult(ASTContext &Ctx,
                                 const CodeCompletionResult &R) {
  auto T = typeOfCompletion(R);
  if (!T)
    return None;
  return encode(Ctx, *T);
}

} // namespace clangd
} // namespace clang
