text: //===--- CodeCompletion.cpp - Code completion implementation --------------===//
  //
  // This source file is part of the Swift.org open source project
  //
  // Copyright (c) 2014 - 2018 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
  //
  //===----------------------------------------------------------------------===//
  
  #include "swift/IDE/CodeCompletion.h"
  #include "CodeCompletionDiagnostics.h"
  #include "CodeCompletionResultBuilder.h"
  #include "ExprContextAnalysis.h"
  #include "swift/AST/ASTPrinter.h"
  #include "swift/AST/ASTWalker.h"
  #include "swift/AST/Comment.h"
  #include "swift/AST/ImportCache.h"
  #include "swift/AST/Initializer.h"
  #include "swift/AST/GenericSignature.h"
  #include "swift/AST/LazyResolver.h"
  #include "swift/AST/NameLookup.h"
  #include "swift/AST/ParameterList.h"
  #include "swift/AST/ProtocolConformance.h"
  #include "swift/AST/SourceFile.h"
  #include "swift/AST/SubstitutionMap.h"
  #include "swift/AST/USRGeneration.h"
  #include "swift/Basic/Defer.h"
  #include "swift/Basic/LLVM.h"
  #include "swift/ClangImporter/ClangImporter.h"
  #include "swift/ClangImporter/ClangModule.h"
  #include "swift/Frontend/FrontendOptions.h"
  #include "swift/IDE/CodeCompletionCache.h"
  #include "swift/IDE/CodeCompletionResultPrinter.h"
  #include "swift/IDE/Utils.h"
  #include "swift/Parse/CodeCompletionCallbacks.h"
  #include "swift/Sema/IDETypeChecking.h"
  #include "swift/Sema/CodeCompletionTypeChecking.h"
  #include "swift/Syntax/SyntaxKind.h"
  #include "swift/Strings.h"
  #include "swift/Subsystems.h"
  #include "clang/AST/ASTContext.h"
  #include "clang/AST/Attr.h"
  #include "clang/AST/Comment.h"
  #include "clang/AST/CommentVisitor.h"
  #include "clang/AST/Decl.h"
  #include "clang/Basic/Module.h"
  #include "clang/Index/USRGeneration.h"
  #include "llvm/ADT/SmallString.h"
  #include "llvm/ADT/StringRef.h"
  #include "llvm/Support/Compiler.h"
  #include "llvm/Support/raw_ostream.h"
  #include "llvm/Support/SaveAndRestore.h"
  #include <algorithm>
  #include <string>
  
  using namespace swift;
  using namespace ide;
  
  using NotRecommendedReason = CodeCompletionResult::NotRecommendedReason;
  
  using DeclFilter = std::function<bool(ValueDecl *, DeclVisibilityKind)>;
  static bool DefaultFilter(ValueDecl* VD, DeclVisibilityKind Kind) {
    return true;
  }
  static bool KeyPathFilter(ValueDecl* decl, DeclVisibilityKind) {
    return isa<TypeDecl>(decl) ||
           (isa<VarDecl>(decl) && decl->getDeclContext()->isTypeContext());
  }
  
  static bool SwiftKeyPathFilter(ValueDecl* decl, DeclVisibilityKind) {
    switch(decl->getKind()){
    case DeclKind::Var:
    case DeclKind::Subscript:
      return true;
    default:
      return false;
    }
  }
  
  std::string swift::ide::removeCodeCompletionTokens(
      StringRef Input, StringRef TokenName, unsigned *CompletionOffset) {
    assert(TokenName.size() >= 1);
  
    *CompletionOffset = ~0U;
  
    std::string CleanFile;
    CleanFile.reserve(Input.size());
    const std::string Token = std::string("#^") + TokenName.str() + "^#";
  
    for (const char *Ptr = Input.begin(), *End = Input.end();
         Ptr != End; ++Ptr) {
      const char C = *Ptr;
      if (C == '#' && Ptr <= End - Token.size() &&
          StringRef(Ptr, Token.size()) == Token) {
        Ptr += Token.size() - 1;
        *CompletionOffset = CleanFile.size();
        CleanFile += '\0';
        continue;
      }
      if (C == '#' && Ptr <= End - 2 && Ptr[1] == '^') {
        do {
          ++Ptr;
        } while (Ptr < End && *Ptr != '#');
        if (Ptr == End)
          break;
        continue;
      }
      CleanFile += C;
    }
    return CleanFile;
  }
  
  llvm::StringRef swift::ide::copyString(llvm::BumpPtrAllocator &Allocator,
                                         llvm::StringRef Str) {
    char *Buffer = Allocator.Allocate<char>(Str.size());
    std::copy(Str.begin(), Str.end(), Buffer);
    return llvm::StringRef(Buffer, Str.size());
  }
  
  const char *swift::ide::copyCString(llvm::BumpPtrAllocator &Allocator,
                                      llvm::StringRef Str) {
    char *Buffer = Allocator.Allocate<char>(Str.size() + 1);
    std::copy(Str.begin(), Str.end(), Buffer);
    Buffer[Str.size()] = '\0';
    return Buffer;
  }
  
  CodeCompletionString::CodeCompletionString(ArrayRef<Chunk> Chunks) {
    std::uninitialized_copy(Chunks.begin(), Chunks.end(),
                            getTrailingObjects<Chunk>());
    NumChunks = Chunks.size();
  }
  
  CodeCompletionString *CodeCompletionString::create(llvm::BumpPtrAllocator &Allocator,
                                                     ArrayRef<Chunk> Chunks) {
    void *CCSMem = Allocator.Allocate(totalSizeToAlloc<Chunk>(Chunks.size()),
                                      alignof(CodeCompletionString));
    return new (CCSMem) CodeCompletionString(Chunks);
  }
  
  void CodeCompletionString::print(raw_ostream &OS) const {
  
    unsigned PrevNestingLevel = 0;
    SmallVector<StringRef, 3> closeTags;
  
    auto chunks = getChunks();
    for (auto I = chunks.begin(), E = chunks.end(); I != E; ++I) {
      while (I->endsPreviousNestedGroup(PrevNestingLevel)) {
        OS << closeTags.pop_back_val();
        --PrevNestingLevel;
      }
      switch (I->getKind()) {
      using ChunkKind = Chunk::ChunkKind;
      case ChunkKind::AccessControlKeyword:
      case ChunkKind::DeclAttrKeyword:
      case ChunkKind::DeclAttrParamKeyword:
      case ChunkKind::OverrideKeyword:
      case ChunkKind::EffectsSpecifierKeyword:
      case ChunkKind::DeclIntroducer:
      case ChunkKind::Text:
      case ChunkKind::LeftParen:
      case ChunkKind::RightParen:
      case ChunkKind::LeftBracket:
      case ChunkKind::RightBracket:
      case ChunkKind::LeftAngle:
      case ChunkKind::RightAngle:
      case ChunkKind::Dot:
      case ChunkKind::Ellipsis:
      case ChunkKind::Comma:
      case ChunkKind::ExclamationMark:
      case ChunkKind::QuestionMark:
      case ChunkKind::Ampersand:
      case ChunkKind::Equal:
      case ChunkKind::Whitespace:
      case ChunkKind::Keyword:
      case ChunkKind::Attribute:
      case ChunkKind::BaseName:
      case ChunkKind::TypeIdSystem:
      case ChunkKind::TypeIdUser:
      case ChunkKind::CallArgumentName:
      case ChunkKind::CallArgumentColon:
      case ChunkKind::CallArgumentType:
      case ChunkKind::ParameterDeclExternalName:
      case ChunkKind::ParameterDeclLocalName:
      case ChunkKind::ParameterDeclColon:
      case ChunkKind::DeclAttrParamColon:
      case ChunkKind::GenericParameterName:
        if (I->isAnnotation())
          OS << "['" << I->getText() << "']";
        else
          OS << I->getText();
        break;
      case ChunkKind::CallArgumentInternalName:
        OS << "(" << I->getText() << ")";
        break;
      case ChunkKind::CallArgumentClosureType:
        OS << "##" << I->getText();
        break;
      case ChunkKind::OptionalBegin:
      case ChunkKind::CallArgumentBegin:
      case ChunkKind::GenericParameterBegin:
        OS << "{#";
        closeTags.emplace_back("#}");
        break;
      case ChunkKind::DynamicLookupMethodCallTail:
      case ChunkKind::OptionalMethodCallTail:
        OS << I->getText();
        break;
      case ChunkKind::GenericParameterClauseBegin:
      case ChunkKind::GenericRequirementClauseBegin:
      case ChunkKind::CallArgumentTypeBegin:
      case ChunkKind::DefaultArgumentClauseBegin:
      case ChunkKind::ParameterDeclBegin:
      case ChunkKind::EffectsSpecifierClauseBegin:
      case ChunkKind::DeclResultTypeClauseBegin:
      case ChunkKind::ParameterDeclTypeBegin:
      case ChunkKind::AttributeAndModifierListBegin:
        assert(I->getNestingLevel() == PrevNestingLevel + 1);
        closeTags.emplace_back("");
        break;
      case ChunkKind::TypeAnnotationBegin:
        OS << "[#";
        closeTags.emplace_back("#]");
        break;
      case ChunkKind::TypeAnnotation:
        OS << "[#" << I->getText() << "#]";
        break;
      case ChunkKind::CallArgumentClosureExpr:
        OS << " {" << I->getText() << "|}";
        break;
      case ChunkKind::BraceStmtWithCursor:
        OS << " {|}";
        break;
      }
      PrevNestingLevel = I->getNestingLevel();
    }
    while (PrevNestingLevel > 0) {
      OS << closeTags.pop_back_val();
      --PrevNestingLevel;
    }
  
    assert(closeTags.empty());
  }
  
  void CodeCompletionString::dump() const {
    llvm::raw_ostream &OS = llvm::errs();
  
    OS << "Chunks: \n";
    for (auto &chunk : getChunks()) {
      OS << "- ";
      for (unsigned i = 0, e = chunk.getNestingLevel(); i != e; ++i)
        OS << "| ";
      OS << "(";
  
      switch (chunk.getKind()) {
  #define CASE(K) case Chunk::ChunkKind::K: OS << #K; break;
      CASE(AccessControlKeyword)
      CASE(DeclAttrKeyword)
      CASE(DeclAttrParamKeyword)
      CASE(OverrideKeyword)
      CASE(EffectsSpecifierKeyword)
      CASE(DeclIntroducer)
      CASE(Keyword)
      CASE(Attribute)
      CASE(Text)
      CASE(BaseName)
      CASE(OptionalBegin)
      CASE(LeftParen)
      CASE(RightParen)
      CASE(LeftBracket)
      CASE(RightBracket)
      CASE(LeftAngle)
      CASE(RightAngle)
      CASE(Dot)
      CASE(Ellipsis)
      CASE(Comma)
      CASE(ExclamationMark)
      CASE(QuestionMark)
      CASE(Ampersand)
      CASE(Equal)
      CASE(Whitespace)
      CASE(GenericParameterClauseBegin)
      CASE(GenericRequirementClauseBegin)
      CASE(GenericParameterBegin)
      CASE(GenericParameterName)
      CASE(CallArgumentBegin)
      CASE(CallArgumentName)
      CASE(CallArgumentInternalName)
      CASE(CallArgumentColon)
      CASE(DeclAttrParamColon)
      CASE(CallArgumentType)
      CASE(CallArgumentTypeBegin)
      CASE(TypeIdSystem)
      CASE(TypeIdUser)
      CASE(CallArgumentClosureType)
      CASE(CallArgumentClosureExpr)
      CASE(DynamicLookupMethodCallTail)
      CASE(OptionalMethodCallTail)
      CASE(ParameterDeclBegin)
      CASE(ParameterDeclExternalName)
      CASE(ParameterDeclLocalName)
      CASE(ParameterDeclColon)
      CASE(ParameterDeclTypeBegin)
      CASE(DefaultArgumentClauseBegin)
      CASE(EffectsSpecifierClauseBegin)
      CASE(DeclResultTypeClauseBegin)
      CASE(AttributeAndModifierListBegin)
      CASE(TypeAnnotation)
      CASE(TypeAnnotationBegin)
      CASE(BraceStmtWithCursor)
      }
      if (chunk.isAnnotation())
        OS << " [annotation]";
      if (chunk.hasText()) {
        OS << " \"";
        OS.write_escaped(chunk.getText());
        OS << "\"";
      }
      OS << ")\n";
    }
  }
  
  CodeCompletionDeclKind
  CodeCompletionResult::getCodeCompletionDeclKind(const Decl *D) {
    switch (D->getKind()) {
    case DeclKind::Import:
    case DeclKind::Extension:
    case DeclKind::PatternBinding:
    case DeclKind::EnumCase:
    case DeclKind::TopLevelCode:
    case DeclKind::IfConfig:
    case DeclKind::PoundDiagnostic:
    case DeclKind::MissingMember:
    case DeclKind::OpaqueType:
      llvm_unreachable("not expecting such a declaration result");
    case DeclKind::Module:
      return CodeCompletionDeclKind::Module;
    case DeclKind::TypeAlias:
      return CodeCompletionDeclKind::TypeAlias;
    case DeclKind::AssociatedType:
      return CodeCompletionDeclKind::AssociatedType;
    case DeclKind::GenericTypeParam:
      return CodeCompletionDeclKind::GenericTypeParam;
    case DeclKind::Enum:
      return CodeCompletionDeclKind::Enum;
    case DeclKind::Struct:
      return CodeCompletionDeclKind::Struct;
    case DeclKind::Class:
      return CodeCompletionDeclKind::Class;
    case DeclKind::Protocol:
      return CodeCompletionDeclKind::Protocol;
    case DeclKind::Var:
    case DeclKind::Param: {
      auto DC = D->getDeclContext();
      if (DC->isTypeContext()) {
        if (cast<VarDecl>(D)->isStatic())
          return CodeCompletionDeclKind::StaticVar;
        else
          return CodeCompletionDeclKind::InstanceVar;
      }
      if (DC->isLocalContext())
        return CodeCompletionDeclKind::LocalVar;
      return CodeCompletionDeclKind::GlobalVar;
    }
    case DeclKind::Constructor:
      return CodeCompletionDeclKind::Constructor;
    case DeclKind::Destructor:
      return CodeCompletionDeclKind::Destructor;
    case DeclKind::Accessor:
    case DeclKind::Func: {
      auto DC = D->getDeclContext();
      auto FD = cast<FuncDecl>(D);
      if (DC->isTypeContext()) {
        if (FD->isStatic())
          return CodeCompletionDeclKind::StaticMethod;
        return CodeCompletionDeclKind::InstanceMethod;
      }
      if (FD->isOperator()) {
        if (auto op = FD->getOperatorDecl()) {
          switch (op->getKind()) {
          case DeclKind::PrefixOperator:
            return CodeCompletionDeclKind::PrefixOperatorFunction;
          case DeclKind::PostfixOperator:
            return CodeCompletionDeclKind::PostfixOperatorFunction;
          case DeclKind::InfixOperator:
            return CodeCompletionDeclKind::InfixOperatorFunction;
          default:
            llvm_unreachable("unexpected operator kind");
          }
        } else {
          return CodeCompletionDeclKind::InfixOperatorFunction;
        }
      }
      return CodeCompletionDeclKind::FreeFunction;
    }
    case DeclKind::InfixOperator:
      return CodeCompletionDeclKind::InfixOperatorFunction;
    case DeclKind::PrefixOperator:
      return CodeCompletionDeclKind::PrefixOperatorFunction;
    case DeclKind::PostfixOperator:
      return CodeCompletionDeclKind::PostfixOperatorFunction;
    case DeclKind::PrecedenceGroup:
      return CodeCompletionDeclKind::PrecedenceGroup;
    case DeclKind::EnumElement:
      return CodeCompletionDeclKind::EnumElement;
    case DeclKind::Subscript:
      return CodeCompletionDeclKind::Subscript;
    }
    llvm_unreachable("invalid DeclKind");
  }
  
  bool CodeCompletionResult::getDeclIsSystem(const Decl *D) {
    return D->getModuleContext()->isSystemModule();
  }
  
  void CodeCompletionResult::printPrefix(raw_ostream &OS) const {
    llvm::SmallString<64> Prefix;
    switch (getKind()) {
    case ResultKind::Declaration:
      Prefix.append("Decl");
      switch (getAssociatedDeclKind()) {
      case CodeCompletionDeclKind::Class:
        Prefix.append("[Class]");
        break;
      case CodeCompletionDeclKind::Struct:
        Prefix.append("[Struct]");
        break;
      case CodeCompletionDeclKind::Enum:
        Prefix.append("[Enum]");
        break;
      case CodeCompletionDeclKind::EnumElement:
        Prefix.append("[EnumElement]");
        break;
      case CodeCompletionDeclKind::Protocol:
        Prefix.append("[Protocol]");
        break;
      case CodeCompletionDeclKind::TypeAlias:
        Prefix.append("[TypeAlias]");
        break;
      case CodeCompletionDeclKind::AssociatedType:
        Prefix.append("[AssociatedType]");
        break;
      case CodeCompletionDeclKind::GenericTypeParam:
        Prefix.append("[GenericTypeParam]");
        break;
      case CodeCompletionDeclKind::Constructor:
        Prefix.append("[Constructor]");
        break;
      case CodeCompletionDeclKind::Destructor:
        Prefix.append("[Destructor]");
        break;
      case CodeCompletionDeclKind::Subscript:
        Prefix.append("[Subscript]");
        break;
      case CodeCompletionDeclKind::StaticMethod:
        Prefix.append("[StaticMethod]");
        break;
      case CodeCompletionDeclKind::InstanceMethod:
        Prefix.append("[InstanceMethod]");
        break;
      case CodeCompletionDeclKind::PrefixOperatorFunction:
        Prefix.append("[PrefixOperatorFunction]");
        break;
      case CodeCompletionDeclKind::PostfixOperatorFunction:
        Prefix.append("[PostfixOperatorFunction]");
        break;
      case CodeCompletionDeclKind::InfixOperatorFunction:
        Prefix.append("[InfixOperatorFunction]");
        break;
      case CodeCompletionDeclKind::FreeFunction:
        Prefix.append("[FreeFunction]");
        break;
      case CodeCompletionDeclKind::StaticVar:
        Prefix.append("[StaticVar]");
        break;
      case CodeCompletionDeclKind::InstanceVar:
        Prefix.append("[InstanceVar]");
        break;
      case CodeCompletionDeclKind::LocalVar:
        Prefix.append("[LocalVar]");
        break;
      case CodeCompletionDeclKind::GlobalVar:
        Prefix.append("[GlobalVar]");
        break;
      case CodeCompletionDeclKind::Module:
        Prefix.append("[Module]");
        break;
      case CodeCompletionDeclKind::PrecedenceGroup:
        Prefix.append("[PrecedenceGroup]");
        break;
      }
      break;
    case ResultKind::Keyword:
      Prefix.append("Keyword");
      switch (getKeywordKind()) {
      case CodeCompletionKeywordKind::None:
        break;
  #define KEYWORD(X) case CodeCompletionKeywordKind::kw_##X: \
        Prefix.append("[" #X "]"); \
        break;
  #define POUND_KEYWORD(X) case CodeCompletionKeywordKind::pound_##X: \
        Prefix.append("[#" #X "]"); \
        break;
  #include "swift/Syntax/TokenKinds.def"
      }
      break;
    case ResultKind::Pattern:
      Prefix.append("Pattern");
      break;
    case ResultKind::Literal:
      Prefix.append("Literal");
      switch (getLiteralKind()) {
      case CodeCompletionLiteralKind::ArrayLiteral:
        Prefix.append("[Array]");
        break;
      case CodeCompletionLiteralKind::BooleanLiteral:
        Prefix.append("[Boolean]");
        break;
      case CodeCompletionLiteralKind::ColorLiteral:
        Prefix.append("[_Color]");
        break;
      case CodeCompletionLiteralKind::ImageLiteral:
        Prefix.append("[_Image]");
        break;
      case CodeCompletionLiteralKind::DictionaryLiteral:
        Prefix.append("[Dictionary]");
        break;
      case CodeCompletionLiteralKind::IntegerLiteral:
        Prefix.append("[Integer]");
        break;
      case CodeCompletionLiteralKind::NilLiteral:
        Prefix.append("[Nil]");
        break;
      case CodeCompletionLiteralKind::StringLiteral:
        Prefix.append("[String]");
        break;
      case CodeCompletionLiteralKind::Tuple:
        Prefix.append("[Tuple]");
        break;
      }
      break;
    case ResultKind::BuiltinOperator:
      Prefix.append("BuiltinOperator");
      break;
    }
    Prefix.append("/");
    switch (getSemanticContext()) {
    case SemanticContextKind::None:
      Prefix.append("None");
      break;
    case SemanticContextKind::Local:
      Prefix.append("Local");
      break;
    case SemanticContextKind::CurrentNominal:
      Prefix.append("CurrNominal");
      break;
    case SemanticContextKind::Super:
      Prefix.append("Super");
      break;
    case SemanticContextKind::OutsideNominal:
      Prefix.append("OutNominal");
      break;
    case SemanticContextKind::CurrentModule:
      Prefix.append("CurrModule");
      break;
    case SemanticContextKind::OtherModule:
      Prefix.append("OtherModule");
      if (!ModuleName.empty())
        Prefix.append((Twine("[") + ModuleName + "]").str());
      break;
    }
    if (getFlair().toRaw()) {
      Prefix.append("/Flair[");
      bool isFirstFlair = true;
  #define PRINT_FLAIR(KIND, NAME) \
      if (getFlair().contains(CodeCompletionFlairBit::KIND)) { \
        if (isFirstFlair) { isFirstFlair = false; } \
        else { Prefix.append(","); } \
        Prefix.append(NAME); \
      }
      PRINT_FLAIR(ExpressionSpecific, "ExprSpecific");
      PRINT_FLAIR(SuperChain, "SuperChain");
      PRINT_FLAIR(ArgumentLabels, "ArgLabels");
      PRINT_FLAIR(CommonKeywordAtCurrentPosition, "CommonKeyword")
      PRINT_FLAIR(RareKeywordAtCurrentPosition, "RareKeyword")
      PRINT_FLAIR(RareTypeAtCurrentPosition, "RareType")
      PRINT_FLAIR(ExpressionAtNonScriptOrMainFileScope, "ExprAtFileScope")
      Prefix.append("]");
    }
    if (NotRecommended)
      Prefix.append("/NotRecommended");
    if (IsSystem)
      Prefix.append("/IsSystem");
    if (NumBytesToErase != 0) {
      Prefix.append("/Erase[");
      Prefix.append(Twine(NumBytesToErase).str());
      Prefix.append("]");
    }
    switch (getExpectedTypeRelation()) {
      case ExpectedTypeRelation::Invalid:
        Prefix.append("/TypeRelation[Invalid]");
        break;
      case ExpectedTypeRelation::Identical:
        Prefix.append("/TypeRelation[Identical]");
        break;
      case ExpectedTypeRelation::Convertible:
        Prefix.append("/TypeRelation[Convertible]");
        break;
      case ExpectedTypeRelation::NotApplicable:
      case ExpectedTypeRelation::Unknown:
      case ExpectedTypeRelation::Unrelated:
        break;
    }
  
    Prefix.append(": ");
    while (Prefix.size() < 36) {
      Prefix.append(" ");
    }
    OS << Prefix;
  }
  
  void CodeCompletionResult::dump() const {
    printPrefix(llvm::errs());
    CompletionString->print(llvm::errs());
    llvm::errs() << "\n";
  }
  
  CodeCompletionResult *
  CodeCompletionResult::withFlair(CodeCompletionFlair newFlair,
                                  CodeCompletionResultSink &Sink) {
    if (Kind == ResultKind::Declaration) {
      return new (*Sink.Allocator) CodeCompletionResult(
          getSemanticContext(), newFlair, getNumBytesToErase(),
          getCompletionString(), getAssociatedDeclKind(), isSystem(),
          getModuleName(), getNotRecommendedReason(), getDiagnosticSeverity(),
          getDiagnosticMessage(), getBriefDocComment(), getAssociatedUSRs(),
          getExpectedTypeRelation(),
          isOperator() ? getOperatorKind() : CodeCompletionOperatorKind::None);
    } else {
      return new (*Sink.Allocator) CodeCompletionResult(
          getKind(), getSemanticContext(), newFlair, getNumBytesToErase(),
          getCompletionString(), getExpectedTypeRelation(),
          isOperator() ? getOperatorKind() : CodeCompletionOperatorKind::None);
    }
  }
  
  void CodeCompletionResultBuilder::withNestedGroup(
      CodeCompletionString::Chunk::ChunkKind Kind,
      llvm::function_ref<void()> body) {
    ++CurrentNestingLevel;
    addSimpleChunk(Kind);
    body();
    --CurrentNestingLevel;
  }
  
  void CodeCompletionResultBuilder::addChunkWithText(
      CodeCompletionString::Chunk::ChunkKind Kind, StringRef Text) {
    addChunkWithTextNoCopy(Kind, copyString(*Sink.Allocator, Text));
  }
  
  void CodeCompletionResultBuilder::setAssociatedDecl(const Decl *D) {
    assert(Kind == CodeCompletionResult::ResultKind::Declaration);
  
    AssociatedDecl = D;
  
    if (auto *ClangD = D->getClangDecl())
      CurrentModule = ClangD->getImportedOwningModule();
    // FIXME: macros
    // FIXME: imported header module
  
    if (!CurrentModule) {
      ModuleDecl *MD = D->getModuleContext();
  
      // If this is an underscored cross-import overlay, map it to the underlying
      // module that declares it instead.
      if (ModuleDecl *Declaring = MD->getDeclaringModuleIfCrossImportOverlay())
        MD = Declaring;
  
      CurrentModule = MD;
    }
  
    if (D->getAttrs().getDeprecated(D->getASTContext()))
      setNotRecommended(NotRecommendedReason::Deprecated);
    else if (D->getAttrs().getSoftDeprecated(D->getASTContext()))
      setNotRecommended(NotRecommendedReason::SoftDeprecated);
  
    if (D->getClangNode()) {
      if (auto *ClangD = D->getClangDecl()) {
        const auto &ClangContext = ClangD->getASTContext();
        if (const clang::RawComment *RC =
            ClangContext.getRawCommentForAnyRedecl(ClangD)) {
          setBriefDocComment(RC->getBriefText(ClangContext));
        }
      }
    } else {
      setBriefDocComment(AssociatedDecl->getBriefComment());
    }
  }
  
  namespace {
  
  /// 'ASTPrinter' printing to 'CodeCompletionString' with appropriate ChunkKind.
  /// This is mainly used for printing types and override completions.
  class CodeCompletionStringPrinter : public ASTPrinter {
  protected:
    using ChunkKind = CodeCompletionString::Chunk::ChunkKind;
  
  private:
    CodeCompletionResultBuilder &Builder;
    SmallString<16> Buffer;
    ChunkKind CurrChunkKind = ChunkKind::Text;
    ChunkKind NextChunkKind = ChunkKind::Text;
    SmallVector<PrintStructureKind, 2> StructureStack;
    unsigned int TypeDepth = 0;
    bool InPreamble = false;
  
    bool isCurrentStructureKind(PrintStructureKind Kind) const {
      return !StructureStack.empty() && StructureStack.back() == Kind;
    }
  
    bool isInType() const {
      return TypeDepth > 0;
    }
  
    Optional<ChunkKind>
    getChunkKindForPrintNameContext(PrintNameContext context) const {
      switch (context) {
      case PrintNameContext::Keyword:
        if(isCurrentStructureKind(PrintStructureKind::EffectsSpecifiers)) {
          return ChunkKind::EffectsSpecifierKeyword;
        }
        return ChunkKind::Keyword;
      case PrintNameContext::IntroducerKeyword:
        return ChunkKind::DeclIntroducer;
      case PrintNameContext::Attribute:
        return ChunkKind::Attribute;
      case PrintNameContext::FunctionParameterExternal:
        if (isInType()) {
          return None;
        }
        return ChunkKind::ParameterDeclExternalName;
      case PrintNameContext::FunctionParameterLocal:
        if (isInType()) {
          return None;
        }
        return ChunkKind::ParameterDeclLocalName;
      default:
        return None;
      }
    }
  
    Optional<ChunkKind>
    getChunkKindForStructureKind(PrintStructureKind Kind) const {
      switch (Kind) {
      case PrintStructureKind::FunctionParameter:
        if (isInType()) {
          return None;
        }
        return ChunkKind::ParameterDeclBegin;
      case PrintStructureKind::DefaultArgumentClause:
        return ChunkKind::DefaultArgumentClauseBegin;
      case PrintStructureKind::DeclGenericParameterClause:
        return ChunkKind::GenericParameterClauseBegin;
      case PrintStructureKind::DeclGenericRequirementClause:
        return ChunkKind::GenericRequirementClauseBegin;
      case PrintStructureKind::EffectsSpecifiers:
        return ChunkKind::EffectsSpecifierClauseBegin;
      case PrintStructureKind::DeclResultTypeClause:
        return ChunkKind::DeclResultTypeClauseBegin;
      case PrintStructureKind::FunctionParameterType:
        return ChunkKind::ParameterDeclTypeBegin;
      default:
        return None;
      }
    }
  
    void startNestedGroup(ChunkKind Kind) {
      flush();
      Builder.CurrentNestingLevel++;
      Builder.addSimpleChunk(Kind);
    }
  
    void endNestedGroup() {
      flush();
      Builder.CurrentNestingLevel--;
    }
  
  protected:
    void setNextChunkKind(ChunkKind Kind) {
      NextChunkKind = Kind;
    }
  
  public:
    CodeCompletionStringPrinter(CodeCompletionResultBuilder &Builder) : Builder(Builder) {}
  
    ~CodeCompletionStringPrinter() {
      // Flush the remainings.
      flush();
    }
  
    void flush() {
      if (Buffer.empty())
        return;
      Builder.addChunkWithText(CurrChunkKind, Buffer);
      Buffer.clear();
    }
  
    /// Start \c AttributeAndModifierListBegin group. This must be called before
    /// any attributes/modifiers printed to the output when printing an override
    /// compleion.
    void startPreamble() {
      assert(!InPreamble);
      startNestedGroup(ChunkKind::AttributeAndModifierListBegin);
      InPreamble = true;
    }
  
    /// End the current \c AttributeAndModifierListBegin group if it's still open.
    /// This is automatically called before the main part of the signature.
    void endPremable() {
      if (!InPreamble)
        return;
      InPreamble = false;
      endNestedGroup();
    }
  
    /// Implement \c ASTPrinter .
  public:
    void printText(StringRef Text) override {
      // Detect ': ' and ', ' in parameter clauses.
      // FIXME: Is there a better way?
      if (isCurrentStructureKind(PrintStructureKind::FunctionParameter) &&
          Text == ": ") {
        setNextChunkKind(ChunkKind::ParameterDeclColon);
      } else if (
          isCurrentStructureKind(PrintStructureKind::FunctionParameterList) &&
          Text == ", ") {
        setNextChunkKind(ChunkKind::Comma);
      }
  
      if (CurrChunkKind != NextChunkKind) {
        // If the next desired kind is different from the current buffer, flush
        // the current buffer.
        flush();
        CurrChunkKind = NextChunkKind;
      }
      Buffer.append(Text);
    }
  
    void printTypeRef(
        Type T, const TypeDecl *TD, Identifier Name,
        PrintNameContext NameContext = PrintNameContext::Normal) override {
  
      NextChunkKind = TD->getModuleContext()->isSystemModule()
        ? ChunkKind::TypeIdSystem
        : ChunkKind::TypeIdUser;
  
      ASTPrinter::printTypeRef(T, TD, Name, NameContext);
      NextChunkKind = ChunkKind::Text;
    }
  
    void printDeclLoc(const Decl *D) override {
      endPremable();
      setNextChunkKind(ChunkKind::BaseName);
    }
  
    void printDeclNameEndLoc(const Decl *D) override {
      setNextChunkKind(ChunkKind::Text);
    }
  
    void printNamePre(PrintNameContext context) override {
      if (context == PrintNameContext::IntroducerKeyword)
        endPremable();
      if (auto Kind = getChunkKindForPrintNameContext(context))
        setNextChunkKind(*Kind);
    }
  
    void printNamePost(PrintNameContext context) override {
      if (getChunkKindForPrintNameContext(context))
        setNextChunkKind(ChunkKind::Text);
    }
  
    void printTypePre(const TypeLoc &TL) override {
      ++TypeDepth;
    }
  
    void printTypePost(const TypeLoc &TL) override {
      assert(TypeDepth > 0);
      --TypeDepth;
    }
  
    void printStructurePre(PrintStructureKind Kind, const Decl *D) override {
      StructureStack.push_back(Kind);
  
      if (auto chunkKind = getChunkKindForStructureKind(Kind))
        startNestedGroup(*chunkKind);
    }
  
    void printStructurePost(PrintStructureKind Kind, const Decl *D) override {
      if (getChunkKindForStructureKind(Kind))
        endNestedGroup();
  
      assert(Kind == StructureStack.back());
      StructureStack.pop_back();
    }
  };
  } // namespcae
  
  void CodeCompletionResultBuilder::addCallArgument(
      Identifier Name, Identifier LocalName, Type Ty, Type ContextTy,
      bool IsVarArg, bool IsInOut, bool IsIUO, bool isAutoClosure,
      bool useUnderscoreLabel, bool isLabeledTrailingClosure) {
    ++CurrentNestingLevel;
    using ChunkKind = CodeCompletionString::Chunk::ChunkKind;
  
    addSimpleChunk(ChunkKind::CallArgumentBegin);
  
    if (shouldAnnotateResults()) {
      if (!Name.empty() || !LocalName.empty()) {
        llvm::SmallString<16> EscapedKeyword;
  
        if (!Name.empty()) {
          addChunkWithText(
              CodeCompletionString::Chunk::ChunkKind::CallArgumentName,
              escapeKeyword(Name.str(), false, EscapedKeyword));
  
          if (!LocalName.empty() && Name != LocalName) {
            addChunkWithTextNoCopy(ChunkKind::Text, " ");
            getLastChunk().setIsAnnotation();
            addChunkWithText(ChunkKind::CallArgumentInternalName,
                escapeKeyword(LocalName.str(), false, EscapedKeyword));
            getLastChunk().setIsAnnotation();
          }
        } else {
          assert(!LocalName.empty());
          addChunkWithTextNoCopy(ChunkKind::CallArgumentName, "_");
          getLastChunk().setIsAnnotation();
          addChunkWithTextNoCopy(ChunkKind::Text, " ");
          getLastChunk().setIsAnnotation();
          addChunkWithText(ChunkKind::CallArgumentInternalName,
              escapeKeyword(LocalName.str(), false, EscapedKeyword));
        }
        addChunkWithTextNoCopy(ChunkKind::CallArgumentColon, ": ");
      }
    } else {
      if (!Name.empty()) {
        llvm::SmallString<16> EscapedKeyword;
        addChunkWithText(
            CodeCompletionString::Chunk::ChunkKind::CallArgumentName,
            escapeKeyword(Name.str(), false, EscapedKeyword));
        addChunkWithTextNoCopy(
            CodeCompletionString::Chunk::ChunkKind::CallArgumentColon, ": ");
      } else if (useUnderscoreLabel) {
        addChunkWithTextNoCopy(
            CodeCompletionString::Chunk::ChunkKind::CallArgumentName, "_");
        addChunkWithTextNoCopy(
            CodeCompletionString::Chunk::ChunkKind::CallArgumentColon, ": ");
      } else if (!LocalName.empty()) {
        // Use local (non-API) parameter name if we have nothing else.
        llvm::SmallString<16> EscapedKeyword;
        addChunkWithText(
            CodeCompletionString::Chunk::ChunkKind::CallArgumentInternalName,
              escapeKeyword(LocalName.str(), false, EscapedKeyword));
        addChunkWithTextNoCopy(
            CodeCompletionString::Chunk::ChunkKind::CallArgumentColon, ": ");
      }
    }
  
    // 'inout' arguments are printed specially.
    if (IsInOut) {
      addChunkWithTextNoCopy(
          CodeCompletionString::Chunk::ChunkKind::Ampersand, "&");
      Ty = Ty->getInOutObjectType();
    }
  
    // If the parameter is of the type @autoclosure ()->output, then the
    // code completion should show the parameter of the output type
    // instead of the function type ()->output.
    if (isAutoClosure) {
      // 'Ty' may be ErrorType.
      if (auto funcTy = Ty->getAs<FunctionType>())
        Ty = funcTy->getResult();
    }
  
    PrintOptions PO;
    PO.SkipAttributes = true;
    PO.PrintOptionalAsImplicitlyUnwrapped = IsIUO;
    PO.OpaqueReturnTypePrinting =
        PrintOptions::OpaqueReturnTypePrintingMode::WithoutOpaqueKeyword;
    if (ContextTy)
      PO.setBaseType(ContextTy);
    if (shouldAnnotateResults()) {
      withNestedGroup(ChunkKind::CallArgumentTypeBegin, [&]() {
        CodeCompletionStringPrinter printer(*this);
        auto TL = TypeLoc::withoutLoc(Ty);
        printer.printTypePre(TL);
        Ty->print(printer, PO);
        printer.printTypePost(TL);
      });
    } else {
      std::string TypeName = Ty->getString(PO);
      addChunkWithText(ChunkKind::CallArgumentType, TypeName);
    }
  
    // Look through optional types and type aliases to find out if we have
    // function type.
    Ty = Ty->lookThroughAllOptionalTypes();
    if (auto AFT = Ty->getAs<AnyFunctionType>()) {
      // If this is a closure type, add ChunkKind::CallArgumentClosureType or
      // ChunkKind::CallArgumentClosureExpr for labeled trailing closures.
      PrintOptions PO;
      PO.PrintFunctionRepresentationAttrs =
        PrintOptions::FunctionRepresentationMode::None;
      PO.SkipAttributes = true;
      PO.OpaqueReturnTypePrinting =
          PrintOptions::OpaqueReturnTypePrintingMode::WithoutOpaqueKeyword;
      PO.AlwaysTryPrintParameterLabels = true;
      if (ContextTy)
        PO.setBaseType(ContextTy);
  
      if (isLabeledTrailingClosure) {
        // Expand the closure body.
        SmallString<32> buffer;
        llvm::raw_svector_ostream OS(buffer);
  
        bool firstParam = true;
        for (const auto &param : AFT->getParams()) {
          if (!firstParam)
            OS << ", ";
          firstParam = false;
  
          if (param.hasLabel()) {
            OS << param.getLabel();
          } else if (param.hasInternalLabel()) {
            OS << param.getInternalLabel();
          } else {
            OS << "<#";
            if (param.isInOut())
              OS << "inout ";
            OS << param.getPlainType()->getString(PO);
            if (param.isVariadic())
              OS << "...";
            OS << "#>";
          }
        }
  
        if (!firstParam)
          OS << " in";
  
        addChunkWithText(
           CodeCompletionString::Chunk::ChunkKind::CallArgumentClosureExpr,
           OS.str());
      } else {
        // Add the closure type.
        addChunkWithText(
            CodeCompletionString::Chunk::ChunkKind::CallArgumentClosureType,
            AFT->getString(PO));
      }
    }
  
    if (IsVarArg)
      addEllipsis();
    --CurrentNestingLevel;
  }
  
  void CodeCompletionResultBuilder::addTypeAnnotation(Type T, PrintOptions PO,
                                                      StringRef suffix) {
    T = T->getReferenceStorageReferent();
  
    // Replace '()' with 'Void'.
    if (T->isVoid())
      T = T->getASTContext().getVoidDecl()->getDeclaredInterfaceType();
  
    if (shouldAnnotateResults()) {
      withNestedGroup(CodeCompletionString::Chunk::ChunkKind::TypeAnnotationBegin,
                      [&]() {
                        CodeCompletionStringPrinter printer(*this);
                        auto TL = TypeLoc::withoutLoc(T);
                        printer.printTypePre(TL);
                        T->print(printer, PO);
                        printer.printTypePost(TL);
                        if (!suffix.empty())
                          printer.printText(suffix);
                      });
    } else {
      auto str = T.getString(PO);
      if (!suffix.empty())
        str += suffix.str();
      addTypeAnnotation(str);
    }
  }
  
  StringRef CodeCompletionContext::copyString(StringRef Str) {
    return ::copyString(*CurrentResults.Allocator, Str);
  }
  
  bool shouldCopyAssociatedUSRForDecl(const ValueDecl *VD) {
    // Avoid trying to generate a USR for some declaration types.
    if (isa<AbstractTypeParamDecl>(VD) && !isa<AssociatedTypeDecl>(VD))
      return false;
    if (isa<ParamDecl>(VD))
      return false;
    if (isa<ModuleDecl>(VD))
      return false;
    if (VD->hasClangNode() && !VD->getClangDecl())
      return false;
  
    return true;
  }
  
  template <typename FnTy>
  static void walkValueDeclAndOverriddenDecls(const Decl *D, const FnTy &Fn) {
    if (auto *VD = dyn_cast<ValueDecl>(D)) {
      Fn(VD);
      walkOverriddenDecls(VD, Fn);
    }
  }
  
  ArrayRef<StringRef> copyAssociatedUSRs(llvm::BumpPtrAllocator &Allocator,
                                         const Decl *D) {
    llvm::SmallVector<StringRef, 4> USRs;
    walkValueDeclAndOverriddenDecls(D, [&](llvm::PointerUnion<const ValueDecl*,
                                                    const clang::NamedDecl*> OD) {
      llvm::SmallString<128> SS;
      bool Ignored = true;
      if (auto *OVD = OD.dyn_cast<const ValueDecl*>()) {
        if (shouldCopyAssociatedUSRForDecl(OVD)) {
          llvm::raw_svector_ostream OS(SS);
          Ignored = printValueDeclUSR(OVD, OS);
        }
      } else if (auto *OND = OD.dyn_cast<const clang::NamedDecl*>()) {
        Ignored = clang::index::generateUSRForDecl(OND, SS);
      }
  
      if (!Ignored)
        USRs.push_back(copyString(Allocator, SS));
    });
  
    if (!USRs.empty())
      return copyArray(Allocator, ArrayRef<StringRef>(USRs));
  
    return ArrayRef<StringRef>();
  }
  
  static CodeCompletionResult::ExpectedTypeRelation
  calculateTypeRelation(Type Ty, Type ExpectedTy, const DeclContext *DC) {
    if (Ty.isNull() || ExpectedTy.isNull() ||
        Ty->is<ErrorType>() ||
        ExpectedTy->is<ErrorType>())
      return CodeCompletionResult::ExpectedTypeRelation::Unrelated;
  
    // Equality/Conversion of GenericTypeParameterType won't account for
    // requirements – ignore them
    if (!Ty->hasTypeParameter() && !ExpectedTy->hasTypeParameter()) {
      if (Ty->isEqual(ExpectedTy))
        return CodeCompletionResult::ExpectedTypeRelation::Identical;
      bool isAny = false;
      isAny |= ExpectedTy->isAny();
      isAny |= ExpectedTy->is<ArchetypeType>() &&
               !ExpectedTy->castTo<ArchetypeType>()->hasRequirements();
  
      if (!isAny && isConvertibleTo(Ty, ExpectedTy, /*openArchetypes=*/true,
                                    *const_cast<DeclContext *>(DC)))
        return CodeCompletionResult::ExpectedTypeRelation::Convertible;
    }
    if (auto FT = Ty->getAs<AnyFunctionType>()) {
      if (FT->getResult()->isVoid())
        return CodeCompletionResult::ExpectedTypeRelation::Invalid;
    }
    return CodeCompletionResult::ExpectedTypeRelation::Unrelated;
  }
  
  static CodeCompletionResult::ExpectedTypeRelation
  calculateMaxTypeRelation(Type Ty, const ExpectedTypeContext &typeContext,
                           const DeclContext *DC) {
    if (typeContext.empty())
      return CodeCompletionResult::ExpectedTypeRelation::Unknown;
  
    if (auto funcTy = Ty->getAs<AnyFunctionType>())
      Ty = funcTy->removeArgumentLabels(1);
  
    auto Result = CodeCompletionResult::ExpectedTypeRelation::Unrelated;
    for (auto expectedTy : typeContext.possibleTypes) {
      // Do not use Void type context for a single-expression body, since the
      // implicit return does not constrain the expression.
      //
      //     { ... -> ()  in x } // x can be anything
      //
      // This behaves differently from explicit return, and from non-Void:
      //
      //     { ... -> Int in x }        // x must be Int
      //     { ... -> ()  in return x } // x must be Void
      if (typeContext.isImplicitSingleExpressionReturn && expectedTy->isVoid())
        continue;
  
      Result = std::max(Result, calculateTypeRelation(Ty, expectedTy, DC));
  
      // Map invalid -> unrelated when in a single-expression body, since the
      // input may be incomplete.
      if (typeContext.isImplicitSingleExpressionReturn &&
          Result == CodeCompletionResult::ExpectedTypeRelation::Invalid)
        Result = CodeCompletionResult::ExpectedTypeRelation::Unrelated;
    }
    return Result;
  }
  
  CodeCompletionOperatorKind
  CodeCompletionResult::getCodeCompletionOperatorKind(StringRef name) {
    using CCOK = CodeCompletionOperatorKind;
    using OpPair = std::pair<StringRef, CCOK>;
  
    // This list must be kept in alphabetical order.
    static OpPair ops[] = {
        std::make_pair("!", CCOK::Bang),
        std::make_pair("!=", CCOK::NotEq),
        std::make_pair("!==", CCOK::NotEqEq),
        std::make_pair("%", CCOK::Modulo),
        std::make_pair("%=", CCOK::ModuloEq),
        std::make_pair("&", CCOK::Amp),
        std::make_pair("&&", CCOK::AmpAmp),
        std::make_pair("&*", CCOK::AmpStar),
        std::make_pair("&+", CCOK::AmpPlus),
        std::make_pair("&-", CCOK::AmpMinus),
        std::make_pair("&=", CCOK::AmpEq),
        std::make_pair("(", CCOK::LParen),
        std::make_pair("*", CCOK::Star),
        std::make_pair("*=", CCOK::StarEq),
        std::make_pair("+", CCOK::Plus),
        std::make_pair("+=", CCOK::PlusEq),
        std::make_pair("-", CCOK::Minus),
        std::make_pair("-=", CCOK::MinusEq),
        std::make_pair(".", CCOK::Dot),
        std::make_pair("...", CCOK::DotDotDot),
        std::make_pair("..<", CCOK::DotDotLess),
        std::make_pair("/", CCOK::Slash),
        std::make_pair("/=", CCOK::SlashEq),
        std::make_pair("<", CCOK::Less),
        std::make_pair("<<", CCOK::LessLess),
        std::make_pair("<<=", CCOK::LessLessEq),
        std::make_pair("<=", CCOK::LessEq),
        std::make_pair("=", CCOK::Eq),
        std::make_pair("==", CCOK::EqEq),
        std::make_pair("===", CCOK::EqEqEq),
        std::make_pair(">", CCOK::Greater),
        std::make_pair(">=", CCOK::GreaterEq),
        std::make_pair(">>", CCOK::GreaterGreater),
        std::make_pair(">>=", CCOK::GreaterGreaterEq),
        std::make_pair("?.", CCOK::QuestionDot),
        std::make_pair("^", CCOK::Caret),
        std::make_pair("^=", CCOK::CaretEq),
        std::make_pair("|", CCOK::Pipe),
        std::make_pair("|=", CCOK::PipeEq),
        std::make_pair("||", CCOK::PipePipe),
        std::make_pair("~=", CCOK::TildeEq),
    };
    static auto opsSize = sizeof(ops) / sizeof(ops[0]);
  
    auto I = std::lower_bound(
        ops, &ops[opsSize], std::make_pair(name, CCOK::None),
        [](const OpPair &a, const OpPair &b) { return a.first < b.first; });
  
    if (I == &ops[opsSize] || I->first != name)
      return CCOK::Unknown;
    return I->second;
  }
  
  static StringRef getOperatorName(CodeCompletionString *str) {
    return str->getFirstTextChunk(/*includeLeadingPunctuation=*/true);
  }
  
  CodeCompletionOperatorKind
  CodeCompletionResult::getCodeCompletionOperatorKind(CodeCompletionString *str) {
    return getCodeCompletionOperatorKind(getOperatorName(str));
  }
  
  CodeCompletionResult *CodeCompletionResultBuilder::takeResult() {
    auto *CCS = CodeCompletionString::create(*Sink.Allocator, Chunks);
  
    switch (Kind) {
    case CodeCompletionResult::ResultKind::Declaration: {
      StringRef ModuleName;
      if (CurrentModule) {
        if (Sink.LastModule.first == CurrentModule.getOpaqueValue()) {
          ModuleName = Sink.LastModule.second;
        } else {
          if (auto *C = CurrentModule.dyn_cast<const clang::Module *>()) {
            ModuleName = copyString(*Sink.Allocator, C->getFullModuleName());
          } else {
            ModuleName = copyString(
                *Sink.Allocator,
                CurrentModule.get<const swift::ModuleDecl *>()->getName().str());
          }
          Sink.LastModule.first = CurrentModule.getOpaqueValue();
          Sink.LastModule.second = ModuleName;
        }
      }
  
      CodeCompletionResult *result = new (*Sink.Allocator) CodeCompletionResult(
          SemanticContext, Flair, NumBytesToErase, CCS, AssociatedDecl,
          ModuleName, NotRecReason, copyString(*Sink.Allocator, BriefDocComment),
          copyAssociatedUSRs(*Sink.Allocator, AssociatedDecl),
          ExpectedTypeRelation);
      if (NotRecReason != NotRecommendedReason::None) {
        // FIXME: We should generate the message lazily.
        if (const auto *VD = dyn_cast<ValueDecl>(AssociatedDecl)) {
          CodeCompletionDiagnosticSeverity severity;
          SmallString<256> message;
          llvm::raw_svector_ostream messageOS(message);
          if (!getCompletionDiagnostics(NotRecReason, VD, severity, messageOS))
            result->setDiagnostics(severity,
                                   copyString(*Sink.Allocator, message));
        }
      }
      return result;
    }
  
    case CodeCompletionResult::ResultKind::Keyword:
      return new (*Sink.Allocator)
          CodeCompletionResult(
            KeywordKind, SemanticContext, Flair, NumBytesToErase,
            CCS, ExpectedTypeRelation,
            copyString(*Sink.Allocator, BriefDocComment));
  
    case CodeCompletionResult::ResultKind::BuiltinOperator:
    case CodeCompletionResult::ResultKind::Pattern:
      return new (*Sink.Allocator) CodeCompletionResult(
          Kind, SemanticContext, Flair, NumBytesToErase, CCS,
          ExpectedTypeRelation, CodeCompletionOperatorKind::None,
          copyString(*Sink.Allocator, BriefDocComment));
  
    case CodeCompletionResult::ResultKind::Literal:
      assert(LiteralKind.hasValue());
      return new (*Sink.Allocator)
          CodeCompletionResult(*LiteralKind, SemanticContext, Flair,
                               NumBytesToErase, CCS, ExpectedTypeRelation);
    }
  
    llvm_unreachable("Unhandled CodeCompletionResult in switch.");
  }
  
  void CodeCompletionResultBuilder::finishResult() {
    if (!Cancelled)
      Sink.Results.push_back(takeResult());
  }
  
  
  MutableArrayRef<CodeCompletionResult *> CodeCompletionContext::takeResults() {
    // Copy pointers to the results.
    const size_t Count = CurrentResults.Results.size();
    CodeCompletionResult **Results =
        CurrentResults.Allocator->Allocate<CodeCompletionResult *>(Count);
    std::copy(CurrentResults.Results.begin(), CurrentResults.Results.end(),
              Results);
    CurrentResults.Results.clear();
    return MutableArrayRef<CodeCompletionResult *>(Results, Count);
  }
  
  Optional<unsigned> CodeCompletionString::getFirstTextChunkIndex(
      bool includeLeadingPunctuation) const {
    for (auto i : indices(getChunks())) {
      const Chunk &C = getChunks()[i];
      switch (C.getKind()) {
      using ChunkKind = Chunk::ChunkKind;
      case ChunkKind::Text:
        // Skip white-space only chunks.
        if (C.getText().find_first_not_of(" \r\n") == StringRef::npos)
          continue;
        return i;
      case ChunkKind::CallArgumentName:
      case ChunkKind::CallArgumentInternalName:
      case ChunkKind::ParameterDeclExternalName:
      case ChunkKind::ParameterDeclLocalName:
      case ChunkKind::ParameterDeclColon:
      case ChunkKind::GenericParameterClauseBegin:
      case ChunkKind::GenericRequirementClauseBegin:
      case ChunkKind::GenericParameterName:
      case ChunkKind::LeftParen:
      case ChunkKind::LeftBracket:
      case ChunkKind::Equal:
      case ChunkKind::DeclAttrParamKeyword:
      case ChunkKind::DeclAttrKeyword:
      case ChunkKind::Keyword:
      case ChunkKind::Attribute:
      case ChunkKind::BaseName:
      case ChunkKind::TypeIdSystem:
      case ChunkKind::TypeIdUser:
      case ChunkKind::CallArgumentBegin:
      case ChunkKind::DefaultArgumentClauseBegin:
      case ChunkKind::ParameterDeclBegin:
      case ChunkKind::EffectsSpecifierClauseBegin:
      case ChunkKind::DeclResultTypeClauseBegin:
      case ChunkKind::AttributeAndModifierListBegin:
        return i;
      case ChunkKind::Dot:
      case ChunkKind::ExclamationMark:
      case ChunkKind::QuestionMark:
        if (includeLeadingPunctuation)
          return i;
        continue;
      case ChunkKind::RightParen:
      case ChunkKind::RightBracket:
      case ChunkKind::LeftAngle:
      case ChunkKind::RightAngle:
      case ChunkKind::Ellipsis:
      case ChunkKind::Comma:
      case ChunkKind::Ampersand:
      case ChunkKind::Whitespace:
      case ChunkKind::AccessControlKeyword:
      case ChunkKind::OverrideKeyword:
      case ChunkKind::EffectsSpecifierKeyword:
      case ChunkKind::DeclIntroducer:
      case ChunkKind::CallArgumentColon:
      case ChunkKind::CallArgumentTypeBegin:
      case ChunkKind::CallArgumentType:
      case ChunkKind::CallArgumentClosureType:
      case ChunkKind::CallArgumentClosureExpr:
      case ChunkKind::ParameterDeclTypeBegin:
      case ChunkKind::DeclAttrParamColon:
      case ChunkKind::OptionalBegin:
      case ChunkKind::GenericParameterBegin:
      case ChunkKind::DynamicLookupMethodCallTail:
      case ChunkKind::OptionalMethodCallTail:
      case ChunkKind::TypeAnnotation:
      case ChunkKind::TypeAnnotationBegin:
        continue;
  
      case ChunkKind::BraceStmtWithCursor:
        llvm_unreachable("should have already extracted the text");
      }
    }
    return None;
  }
  
  StringRef
  CodeCompletionString::getFirstTextChunk(bool includeLeadingPunctuation) const {
    Optional<unsigned> Idx = getFirstTextChunkIndex(includeLeadingPunctuation);
    if (Idx.hasValue())
      return getChunks()[*Idx].getText();
    return StringRef();
  }
  
  void CodeCompletionContext::sortCompletionResults(
      MutableArrayRef<CodeCompletionResult *> Results) {
    struct ResultAndName {
      CodeCompletionResult *result;
      std::string name;
    };
  
    // Caching the name of each field is important to avoid unnecessary calls to
    // CodeCompletionString::getName().
    std::vector<ResultAndName> nameCache(Results.size());
    for (unsigned i = 0, n = Results.size(); i < n; ++i) {
      auto *result = Results[i];
      nameCache[i].result = result;
      llvm::raw_string_ostream OS(nameCache[i].name);
      printCodeCompletionResultFilterName(*result, OS);
      OS.flush();
    }
  
    // Sort nameCache, and then transform Results to return the pointers in order.
    std::sort(nameCache.begin(), nameCache.end(),
              [](const ResultAndName &LHS, const ResultAndName &RHS) {
                int Result = StringRef(LHS.name).compare_insensitive(RHS.name);
                // If the case insensitive comparison is equal, then secondary
                // sort order should be case sensitive.
                if (Result == 0)
                  Result = LHS.name.compare(RHS.name);
                return Result < 0;
              });
  
    llvm::transform(nameCache, Results.begin(),
                    [](const ResultAndName &entry) { return entry.result; });
  }
  
  namespace {
  
  class CodeCompletionCallbacksImpl : public CodeCompletionCallbacks {
    CodeCompletionContext &CompletionContext;
    CodeCompletionConsumer &Consumer;
    CodeCompletionExpr *CodeCompleteTokenExpr = nullptr;
    CompletionKind Kind = CompletionKind::None;
    Expr *ParsedExpr = nullptr;
    SourceLoc DotLoc;
    TypeLoc ParsedTypeLoc;
    DeclContext *CurDeclContext = nullptr;
    DeclAttrKind AttrKind;
  
    /// In situations when \c SyntaxKind hints or determines
    /// completions, i.e. a precedence group attribute, this
    /// can be set and used to control the code completion scenario.
    SyntaxKind SyntxKind;
  
    int AttrParamIndex;
    bool IsInSil = false;
    bool HasSpace = false;
    bool ShouldCompleteCallPatternAfterParen = true;
    bool PreferFunctionReferencesToCalls = false;
    bool AttTargetIsIndependent = false;
    bool IsAtStartOfLine = false;
    Optional<DeclKind> AttTargetDK;
    Optional<StmtKind> ParentStmtKind;
  
    SmallVector<StringRef, 3> ParsedKeywords;
    SourceLoc introducerLoc;
  
    std::vector<std::pair<std::string, bool>> SubModuleNameVisibilityPairs;
  
    void addSuperKeyword(CodeCompletionResultSink &Sink) {
      auto *DC = CurDeclContext->getInnermostTypeContext();
      if (!DC)
        return;
      auto *CD = DC->getSelfClassDecl();
      if (!CD)
        return;
      Type ST = CD->getSuperclass();
      if (ST.isNull() || ST->is<ErrorType>())
        return;
  
      CodeCompletionResultBuilder Builder(Sink,
                                          CodeCompletionResult::ResultKind::Keyword,
                                          SemanticContextKind::CurrentNominal,
                                          {});
      if (auto *AFD = dyn_cast<AbstractFunctionDecl>(CurDeclContext)) {
        if (AFD->getOverriddenDecl() != nullptr) {
          Builder.addFlair(CodeCompletionFlairBit::CommonKeywordAtCurrentPosition);
        }
      }
  
      Builder.setKeywordKind(CodeCompletionKeywordKind::kw_super);
      Builder.addKeyword("super");
      Builder.addTypeAnnotation(ST, PrintOptions());
    }
  
    Optional<std::pair<Type, ConcreteDeclRef>> typeCheckParsedExpr() {
      assert(ParsedExpr && "should have an expression");
  
      // Figure out the kind of type-check we'll be performing.
      auto CheckKind = CompletionTypeCheckKind::Normal;
      if (Kind == CompletionKind::KeyPathExprObjC)
        CheckKind = CompletionTypeCheckKind::KeyPath;
  
      // If we've already successfully type-checked the expression for some
      // reason, just return the type.
      // FIXME: if it's ErrorType but we've already typechecked we shouldn't
      // typecheck again. rdar://21466394
      if (CheckKind == CompletionTypeCheckKind::Normal &&
          ParsedExpr->getType() && !ParsedExpr->getType()->is<ErrorType>()) {
        return getReferencedDecl(ParsedExpr);
      }
  
      ConcreteDeclRef ReferencedDecl = nullptr;
      Expr *ModifiedExpr = ParsedExpr;
      if (auto T = getTypeOfCompletionContextExpr(P.Context, CurDeclContext,
                                                  CheckKind, ModifiedExpr,
                                                  ReferencedDecl)) {
        // FIXME: even though we don't apply the solution, the type checker may
        // modify the original expression. We should understand what effect that
        // may have on code completion.
        ParsedExpr = ModifiedExpr;
  
        return std::make_pair(*T, ReferencedDecl);
      }
      return None;
    }
  
    /// \returns true on success, false on failure.
    bool typecheckParsedType() {
      assert(ParsedTypeLoc.getTypeRepr() && "should have a TypeRepr");
      if (ParsedTypeLoc.wasValidated() && !ParsedTypeLoc.isError()) {
        return true;
      }
  
      const auto ty = swift::performTypeResolution(
          ParsedTypeLoc.getTypeRepr(), P.Context,
          /*isSILMode=*/false,
          /*isSILType=*/false,
          CurDeclContext->getGenericEnvironmentOfContext(),
          /*GenericParams=*/nullptr,
          CurDeclContext,
          /*ProduceDiagnostics=*/false);
      ParsedTypeLoc.setType(ty);
      if (!ParsedTypeLoc.isError()) {
        return true;
      }
  
      // It doesn't type check as a type, so see if it's a qualifying module name.
      if (auto *ITR = dyn_cast<IdentTypeRepr>(ParsedTypeLoc.getTypeRepr())) {
        const auto &componentRange = ITR->getComponentRange();
        // If it has more than one component, it can't be a module name.
        if (std::distance(componentRange.begin(), componentRange.end()) != 1)
          return false;
  
        const auto &component = componentRange.front();
        ImportPath::Module::Builder builder(
            component->getNameRef().getBaseIdentifier(),
            component->getLoc());
  
        if (auto Module = Context.getLoadedModule(builder.get()))
          ParsedTypeLoc.setType(ModuleType::get(Module));
        return true;
      }
      return false;
    }
  
  public:
    CodeCompletionCallbacksImpl(Parser &P,
                                CodeCompletionContext &CompletionContext,
                                CodeCompletionConsumer &Consumer)
        : CodeCompletionCallbacks(P), CompletionContext(CompletionContext),
          Consumer(Consumer) {
    }
  
    void setAttrTargetDeclKind(Optional<DeclKind> DK) override {
      if (DK == DeclKind::PatternBinding)
        DK = DeclKind::Var;
      else if (DK == DeclKind::Param)
        // For params, consider the attribute is always for the decl.
        AttTargetIsIndependent = false;
  
      if (!AttTargetIsIndependent)
        AttTargetDK = DK;
    }
  
    void completeDotExpr(CodeCompletionExpr *E, SourceLoc DotLoc) override;
    void completeStmtOrExpr(CodeCompletionExpr *E) override;
    void completePostfixExprBeginning(CodeCompletionExpr *E) override;
    void completeForEachSequenceBeginning(CodeCompletionExpr *E) override;
    void completePostfixExpr(Expr *E, bool hasSpace) override;
    void completePostfixExprParen(Expr *E, Expr *CodeCompletionE) override;
    void completeExprKeyPath(KeyPathExpr *KPE, SourceLoc DotLoc) override;
  
    void completeTypeDeclResultBeginning() override;
    void completeTypeSimpleBeginning() override;
    void completeTypeIdentifierWithDot(IdentTypeRepr *ITR) override;
    void completeTypeIdentifierWithoutDot(IdentTypeRepr *ITR) override;
  
    void completeCaseStmtKeyword() override;
    void completeCaseStmtBeginning(CodeCompletionExpr *E) override;
    void completeDeclAttrBeginning(bool Sil, bool isIndependent) override;
    void completeDeclAttrParam(DeclAttrKind DK, int Index) override;
    void completeEffectsSpecifier(bool hasAsync, bool hasThrows) override;
    void completeInPrecedenceGroup(SyntaxKind SK) override;
    void completeNominalMemberBeginning(
        SmallVectorImpl<StringRef> &Keywords, SourceLoc introducerLoc) override;
    void completeAccessorBeginning(CodeCompletionExpr *E) override;
  
    void completePoundAvailablePlatform() override;
    void completeImportDecl(ImportPath::Builder &Path) override;
    void completeUnresolvedMember(CodeCompletionExpr *E,
                                  SourceLoc DotLoc) override;
    void completeCallArg(CodeCompletionExpr *E, bool isFirst) override;
    void completeLabeledTrailingClosure(CodeCompletionExpr *E,
                                        bool isAtStartOfLine) override;
  
    bool canPerformCompleteLabeledTrailingClosure() const override {
      return true;
    }
  
    void completeReturnStmt(CodeCompletionExpr *E) override;
    void completeYieldStmt(CodeCompletionExpr *E,
                           Optional<unsigned> yieldIndex) override;
    void completeAfterPoundExpr(CodeCompletionExpr *E,
                                Optional<StmtKind> ParentKind) override;
    void completeAfterPoundDirective() override;
    void completePlatformCondition() override;
    void completeGenericRequirement() override;
    void completeAfterIfStmt(bool hasElse) override;
    void completeStmtLabel(StmtKind ParentKind) override;
    void completeForEachPatternBeginning(bool hasTry, bool hasAwait) override;
    void completeTypeAttrBeginning() override;
  
    void doneParsing() override;
  
  private:
    void addKeywords(CodeCompletionResultSink &Sink, bool MaybeFuncBody);
    bool trySolverCompletion(bool MaybeFuncBody);
  };
  } // end anonymous namespace
  
  namespace {
  static bool isTopLevelSubcontext(const DeclContext *DC) {
    for (; DC && DC->isLocalContext(); DC = DC->getParent()) {
      switch (DC->getContextKind()) {
      case DeclContextKind::TopLevelCodeDecl:
        return true;
      case DeclContextKind::AbstractFunctionDecl:
      case DeclContextKind::SubscriptDecl:
      case DeclContextKind::EnumElementDecl:
        return false;
      default:
        continue;
      }
    }
    return false;
  }
  
  static KnownProtocolKind
  protocolForLiteralKind(CodeCompletionLiteralKind kind) {
    switch (kind) {
    case CodeCompletionLiteralKind::ArrayLiteral:
      return KnownProtocolKind::ExpressibleByArrayLiteral;
    case CodeCompletionLiteralKind::BooleanLiteral:
      return KnownProtocolKind::ExpressibleByBooleanLiteral;
    case CodeCompletionLiteralKind::ColorLiteral:
      return KnownProtocolKind::ExpressibleByColorLiteral;
    case CodeCompletionLiteralKind::ImageLiteral:
      return KnownProtocolKind::ExpressibleByImageLiteral;
    case CodeCompletionLiteralKind::DictionaryLiteral:
      return KnownProtocolKind::ExpressibleByDictionaryLiteral;
    case CodeCompletionLiteralKind::IntegerLiteral:
      return KnownProtocolKind::ExpressibleByIntegerLiteral;
    case CodeCompletionLiteralKind::NilLiteral:
      return KnownProtocolKind::ExpressibleByNilLiteral;
    case CodeCompletionLiteralKind::StringLiteral:
      return KnownProtocolKind::ExpressibleByUnicodeScalarLiteral;
    case CodeCompletionLiteralKind::Tuple:
      llvm_unreachable("no such protocol kind");
    }
  
    llvm_unreachable("Unhandled CodeCompletionLiteralKind in switch.");
  }
  
  static Type
  defaultTypeLiteralKind(CodeCompletionLiteralKind kind, ASTContext &Ctx) {
    switch (kind) {
    case CodeCompletionLiteralKind::BooleanLiteral:
      return Ctx.getBoolType();
    case CodeCompletionLiteralKind::IntegerLiteral:
      return Ctx.getIntType();
    case CodeCompletionLiteralKind::StringLiteral:
      return Ctx.getStringType();
    case CodeCompletionLiteralKind::ArrayLiteral:
      return Ctx.getArrayDecl()->getDeclaredType();
    case CodeCompletionLiteralKind::DictionaryLiteral:
      return Ctx.getDictionaryDecl()->getDeclaredType();
    case CodeCompletionLiteralKind::NilLiteral:
    case CodeCompletionLiteralKind::ColorLiteral:
    case CodeCompletionLiteralKind::ImageLiteral:
    case CodeCompletionLiteralKind::Tuple:
      return Type();
    }
  
    llvm_unreachable("Unhandled CodeCompletionLiteralKind in switch.");
  }
  
  /// Whether funcType has a single argument (not including defaulted arguments)
  /// that is of type () -> ().
  static bool hasTrivialTrailingClosure(const FuncDecl *FD,
                                        AnyFunctionType *funcType) {
    ParameterListInfo paramInfo(funcType->getParams(), FD,
                                /*skipCurriedSelf*/ FD->hasCurriedSelf());
  
    if (paramInfo.size() - paramInfo.numNonDefaultedParameters() == 1) {
      auto param = funcType->getParams().back();
      if (!param.isAutoClosure()) {
        if (auto Fn = param.getOldType()->getAs<AnyFunctionType>()) {
          return Fn->getParams().empty() && Fn->getResult()->isVoid();
        }
      }
    }
  
    return false;
  }
  
  /// Returns \c true if \p DC can handles async call.
  static bool canDeclContextHandleAsync(const DeclContext *DC) {
    if (auto *func = dyn_cast<AbstractFunctionDecl>(DC))
      return func->isAsyncContext();
  
    if (auto *closure = dyn_cast<ClosureExpr>(DC)) {
      // See if the closure has 'async' function type.
      if (auto closureType = closure->getType())
        if (auto fnType = closureType->getAs<AnyFunctionType>())
          if (fnType->isAsync())
            return true;
  
      // If the closure doesn't contain any async call in the body, closure itself
      // doesn't have 'async' type even if 'async' closure is expected.
      //   func foo(fn: () async -> Void)
      //   foo { <HERE> }
      // In this case, the closure is wrapped with a 'FunctionConversionExpr'
      // which has 'async' function type.
      struct AsyncClosureChecker: public ASTWalker {
        const ClosureExpr *Target;
        bool Result = false;
  
        AsyncClosureChecker(const ClosureExpr *Target) : Target(Target) {}
  
        std::pair<bool, Expr *> walkToExprPre(Expr *E) override {
          if (E == Target)
            return {false, E};
  
          if (auto conversionExpr = dyn_cast<FunctionConversionExpr>(E)) {
            if (conversionExpr->getSubExpr() == Target) {
              if (conversionExpr->getType()->is<AnyFunctionType>() &&
                  conversionExpr->getType()->castTo<AnyFunctionType>()->isAsync())
                Result = true;
              return {false, E};
            }
          }
          return {true, E};
        }
      } checker(closure);
      closure->getParent()->walkContext(checker);
      return checker.Result;
    }
  
    return false;
  }
  
  /// Returns \c true only if the completion is happening for top-level
  /// declrarations. i.e.:
  ///
  ///     if condition {
  ///       #false#
  ///     }
  ///     expr.#false#
  ///
  ///     #true#
  ///
  ///     struct S {
  ///       #false#
  ///       func foo() {
  ///         #false#
  ///       }
  ///     }
  static bool isCodeCompletionAtTopLevel(const DeclContext *DC) {
    if (DC->isModuleScopeContext())
      return true;
  
    // CC token at top-level is parsed as an expression. If the only element
    // body of the TopLevelCodeDecl is a CodeCompletionExpr without a base
    // expression, the user might be writing a top-level declaration.
    if (const TopLevelCodeDecl *TLCD = dyn_cast<const TopLevelCodeDecl>(DC)) {
      auto body = TLCD->getBody();
      if (!body || body->empty())
        return true;
      if (body->getElements().size() > 1)
        return false;
      auto expr = body->getFirstElement().dyn_cast<Expr *>();
      if (!expr)
        return false;
      if (CodeCompletionExpr *CCExpr = dyn_cast<CodeCompletionExpr>(expr)) {
        if (CCExpr->getBase() == nullptr)
          return true;
      }
    }
  
    return false;
  }
  
  /// Returns \c true if the completion is happening in local context such as
  /// inside function bodies. i.e.:
  ///
  ///     if condition {
  ///       #true#
  ///     }
  ///     expr.#true#
  ///
  ///     #false#
  ///
  ///     struct S {
  ///       #false#
  ///       func foo() {
  ///         #true#
  ///       }
  ///     }
  static bool isCompletionDeclContextLocalContext(DeclContext *DC) {
    if (!DC->isLocalContext())
      return false;
    if (isCodeCompletionAtTopLevel(DC))
      return false;
    return true;
  }
  
  /// Return \c true if the completion happens at top-level of a library file.
  static bool isCodeCompletionAtTopLevelOfLibraryFile(const DeclContext *DC) {
    if (DC->getParentSourceFile()->isScriptMode())
      return false;
    return isCodeCompletionAtTopLevel(DC);
  }
  
  /// Build completions by doing visible decl lookup from a context.
  class CompletionLookup final : public swift::VisibleDeclConsumer {
    CodeCompletionResultSink &Sink;
    ASTContext &Ctx;
    const DeclContext *CurrDeclContext;
    ModuleDecl *CurrModule;
    ClangImporter *Importer;
    CodeCompletionContext *CompletionContext;
  
    enum class LookupKind {
      ValueExpr,
      ValueInDeclContext,
      EnumElement,
      Type,
      TypeInDeclContext,
      ImportFromModule,
      GenericRequirement,
    };
  
    LookupKind Kind;
  
    /// Type of the user-provided expression for LookupKind::ValueExpr
    /// completions.
    Type ExprType;
  
    /// Whether the expr is of statically inferred metatype.
    bool IsStaticMetatype = false;
  
    /// User-provided base type for LookupKind::Type completions.
    Type BaseType;
  
    /// Expected types of the code completion expression.
    ExpectedTypeContext expectedTypeContext;
  
    bool CanCurrDeclContextHandleAsync = false;
    bool HaveDot = false;
    bool IsUnwrappedOptional = false;
    SourceLoc DotLoc;
    bool NeedLeadingDot = false;
  
    bool NeedOptionalUnwrap = false;
    unsigned NumBytesToEraseForOptionalUnwrap = 0;
  
    bool HaveLParen = false;
    bool IsSuperRefExpr = false;
    bool IsSelfRefExpr = false;
    bool IsKeyPathExpr = false;
    bool IsSwiftKeyPathExpr = false;
    bool IsAfterSwiftKeyPathRoot = false;
    bool IsDynamicLookup = false;
    bool IsCrossActorReference = false;
    bool PreferFunctionReferencesToCalls = false;
    bool HaveLeadingSpace = false;
  
    bool CheckForDuplicates = false;
    llvm::DenseSet<std::pair<const Decl *, Type>> PreviouslySeen;
  
    bool IncludeInstanceMembers = false;
  
    /// True if we are code completing inside a static method.
    bool InsideStaticMethod = false;
  
    /// Innermost method that the code completion point is in.
    const AbstractFunctionDecl *CurrentMethod = nullptr;
  
    Optional<SemanticContextKind> ForcedSemanticContext = None;
    bool IsUnresolvedMember = false;
  
  public:
    bool FoundFunctionCalls = false;
    bool FoundFunctionsWithoutFirstKeyword = false;
  
  private:
    bool isForCaching() const {
      return Kind == LookupKind::ImportFromModule;
    }
  
    void foundFunction(const AbstractFunctionDecl *AFD) {
      FoundFunctionCalls = true;
      const DeclName Name = AFD->getName();
      auto ArgNames = Name.getArgumentNames();
      if (ArgNames.empty())
        return;
      if (ArgNames[0].empty())
        FoundFunctionsWithoutFirstKeyword = true;
    }
  
    void foundFunction(const AnyFunctionType *AFT) {
      FoundFunctionCalls = true;
      auto Params = AFT->getParams();
      if (Params.empty())
        return;
      if (Params.size() == 1 && !Params[0].hasLabel()) {
        FoundFunctionsWithoutFirstKeyword = true;
        return;
      }
      if (!Params[0].hasLabel())
        FoundFunctionsWithoutFirstKeyword = true;
    }
  
    /// Returns \c true if \p TAD is usable as a first type of a requirement in
    /// \c where clause for a context.
    /// \p selfTy must be a \c Self type of the context.
    static bool canBeUsedAsRequirementFirstType(Type selfTy, TypeAliasDecl *TAD) {
      auto T = TAD->getDeclaredInterfaceType();
      auto subMap = selfTy->getMemberSubstitutionMap(TAD->getParentModule(), TAD);
      T = T.subst(subMap)->getCanonicalType();
  
      ArchetypeType *archeTy = T->getAs<ArchetypeType>();
      if (!archeTy)
        return false;
      archeTy = archeTy->getRoot();
  
      // For protocol, the 'archeTy' should match with the 'baseTy' which is the
      // dynamic 'Self' type of the protocol. For nominal decls, 'archTy' should
      // be one of the generic params in 'selfTy'. Search 'archeTy' in 'baseTy'.
      return selfTy.findIf([&](Type T) { return archeTy->isEqual(T); });
    }
  
  public:
    struct RequestedResultsTy {
      const ModuleDecl *TheModule;
      bool OnlyTypes;
      bool OnlyPrecedenceGroups;
      bool NeedLeadingDot;
      bool IncludeModuleQualifier;
  
      static RequestedResultsTy fromModule(const ModuleDecl *TheModule) {
        return { TheModule, false, false, false, true };
      }
  
      RequestedResultsTy onlyTypes() const {
        return { TheModule, true, false, NeedLeadingDot, IncludeModuleQualifier };
      }
  
      RequestedResultsTy onlyPrecedenceGroups() const {
        assert(!OnlyTypes && "onlyTypes() already includes precedence groups");
        return { TheModule, false, true, false, true };
      }
  
      RequestedResultsTy needLeadingDot(bool NeedDot) const {
        return {
            TheModule, OnlyTypes, OnlyPrecedenceGroups, NeedDot,
            IncludeModuleQualifier
        };
      }
  
      RequestedResultsTy withModuleQualifier(bool IncludeModule) const {
          return {
              TheModule, OnlyTypes, OnlyPrecedenceGroups, NeedLeadingDot,
              IncludeModule
          };
      }
  
      static RequestedResultsTy toplevelResults() {
        return { nullptr, false, false, false, true };
      }
    };
  
    std::vector<RequestedResultsTy> RequestedCachedResults;
  
  public:
    CompletionLookup(CodeCompletionResultSink &Sink,
                     ASTContext &Ctx,
                     const DeclContext *CurrDeclContext,
                     CodeCompletionContext *CompletionContext = nullptr)
        : Sink(Sink), Ctx(Ctx), CurrDeclContext(CurrDeclContext),
          CurrModule(CurrDeclContext ? CurrDeclContext->getParentModule()
                                     : nullptr),
          Importer(static_cast<ClangImporter *>(CurrDeclContext->getASTContext().
            getClangModuleLoader())),
          CompletionContext(CompletionContext) {
      // Determine if we are doing code completion inside a static method.
      if (CurrDeclContext) {
        CurrentMethod = CurrDeclContext->getInnermostMethodContext();
        if (auto *FD = dyn_cast_or_null<FuncDecl>(CurrentMethod))
          InsideStaticMethod = FD->isStatic();
        CanCurrDeclContextHandleAsync = canDeclContextHandleAsync(CurrDeclContext);
      }
    }
  
    void setHaveDot(SourceLoc DotLoc) {
      HaveDot = true;
      this->DotLoc = DotLoc;
    }
  
    void setIsUnwrappedOptional(bool value) {
      IsUnwrappedOptional = value;
    }
  
    void setIsStaticMetatype(bool value) {
      IsStaticMetatype = value;
    }
  
    void setExpectedTypes(ArrayRef<Type> Types,
                          bool isImplicitSingleExpressionReturn,
                          bool preferNonVoid = false) {
      expectedTypeContext.isImplicitSingleExpressionReturn =
          isImplicitSingleExpressionReturn;
      expectedTypeContext.preferNonVoid = preferNonVoid;
      expectedTypeContext.possibleTypes.clear();
      expectedTypeContext.possibleTypes.reserve(Types.size());
      for (auto T : Types)
        if (T)
          expectedTypeContext.possibleTypes.push_back(T);
    }
  
    void setIdealExpectedType(Type Ty) {
      expectedTypeContext.idealType = Ty;
    }
  
    CodeCompletionContext::TypeContextKind typeContextKind() const {
      if (expectedTypeContext.empty() && !expectedTypeContext.preferNonVoid) {
        return CodeCompletionContext::TypeContextKind::None;
      } else if (expectedTypeContext.isImplicitSingleExpressionReturn) {
        return CodeCompletionContext::TypeContextKind::SingleExpressionBody;
      } else {
        return CodeCompletionContext::TypeContextKind::Required;
      }
    }
  
    bool needDot() const {
      return NeedLeadingDot;
    }
  
    void setHaveLParen(bool Value) {
      HaveLParen = Value;
    }
  
    void setIsSuperRefExpr(bool Value = true) {
      IsSuperRefExpr = Value;
    }
  
    void setIsSelfRefExpr(bool value) { IsSelfRefExpr = value; }
  
    void setIsKeyPathExpr() {
      IsKeyPathExpr = true;
    }
  
    void shouldCheckForDuplicates(bool value = true) {
      CheckForDuplicates = value;
    }
  
    void setIsSwiftKeyPathExpr(bool onRoot) {
      IsSwiftKeyPathExpr = true;
      IsAfterSwiftKeyPathRoot = onRoot;
    }
  
    void setIsDynamicLookup() {
      IsDynamicLookup = true;
    }
  
    void setPreferFunctionReferencesToCalls() {
      PreferFunctionReferencesToCalls = true;
    }
  
    void setHaveLeadingSpace(bool value) { HaveLeadingSpace = value; }
  
    void includeInstanceMembers() {
      IncludeInstanceMembers = true;
    }
  
    bool isHiddenModuleName(Identifier Name) {
      return (Name.str().startswith("_") ||
              Name == Ctx.SwiftShimsModuleName ||
              Name.str() == SWIFT_ONONE_SUPPORT);
    }
  
    void addSubModuleNames(std::vector<std::pair<std::string, bool>>
        &SubModuleNameVisibilityPairs) {
      for (auto &Pair : SubModuleNameVisibilityPairs) {
        CodeCompletionResultBuilder Builder(Sink,
                                            CodeCompletionResult::ResultKind::
                                            Declaration,
                                            SemanticContextKind::None,
                                            expectedTypeContext);
        auto MD = ModuleDecl::create(Ctx.getIdentifier(Pair.first), Ctx);
        Builder.setAssociatedDecl(MD);
        Builder.addBaseName(MD->getNameStr());
        Builder.addTypeAnnotation("Module");
        if (Pair.second)
          Builder.setNotRecommended(NotRecommendedReason::RedundantImport);
      }
    }
  
    void collectImportedModules(llvm::StringSet<> &directImportedModules,
                                llvm::StringSet<> &allImportedModules) {
      SmallVector<ImportedModule, 16> Imported;
      SmallVector<ImportedModule, 16> FurtherImported;
      CurrDeclContext->getParentSourceFile()->getImportedModules(
          Imported,
          {ModuleDecl::ImportFilterKind::Exported,
           ModuleDecl::ImportFilterKind::Default,
           ModuleDecl::ImportFilterKind::ImplementationOnly});
  
      for (ImportedModule &imp : Imported)
        directImportedModules.insert(imp.importedModule->getNameStr());
  
      while (!Imported.empty()) {
        ModuleDecl *MD = Imported.back().importedModule;
        Imported.pop_back();
        if (!allImportedModules.insert(MD->getNameStr()).second)
          continue;
        FurtherImported.clear();
        MD->getImportedModules(FurtherImported,
                               ModuleDecl::ImportFilterKind::Exported);
        Imported.append(FurtherImported.begin(), FurtherImported.end());
      }
    }
  
    void addModuleName(ModuleDecl *MD, Optional<NotRecommendedReason> R = None) {
  
      // Don't add underscored cross-import overlay modules.
      if (MD->getDeclaringModuleIfCrossImportOverlay())
        return;
  
      CodeCompletionResultBuilder Builder(
          Sink,
          CodeCompletionResult::ResultKind::Declaration,
          SemanticContextKind::None,
          expectedTypeContext);
      Builder.setAssociatedDecl(MD);
      Builder.addBaseName(MD->getNameStr());
      Builder.addTypeAnnotation("Module");
      if (R)
        Builder.setNotRecommended(*R);
    }
  
    void addImportModuleNames() {
      SmallVector<Identifier, 0> ModuleNames;
      Ctx.getVisibleTopLevelModuleNames(ModuleNames);
  
      llvm::StringSet<> directImportedModules;
      llvm::StringSet<> allImportedModules;
      collectImportedModules(directImportedModules, allImportedModules);
  
      auto mainModuleName = CurrModule->getName();
      for (auto ModuleName : ModuleNames) {
        if (ModuleName == mainModuleName || isHiddenModuleName(ModuleName))
          continue;
  
        auto MD = ModuleDecl::create(ModuleName, Ctx);
        Optional<NotRecommendedReason> Reason = None;
  
        // Imported modules are not recommended.
        if (directImportedModules.contains(MD->getNameStr())) {
          Reason = NotRecommendedReason::RedundantImport;
        } else if (allImportedModules.contains(MD->getNameStr())) {
          Reason = NotRecommendedReason::RedundantImportIndirect;
        }
  
        addModuleName(MD, Reason);
      }
    }
  
    SemanticContextKind getSemanticContext(const Decl *D,
                                           DeclVisibilityKind Reason,
                                           DynamicLookupInfo dynamicLookupInfo) {
      if (ForcedSemanticContext)
        return *ForcedSemanticContext;
  
      switch (Reason) {
      case DeclVisibilityKind::LocalVariable:
      case DeclVisibilityKind::FunctionParameter:
      case DeclVisibilityKind::GenericParameter:
        return SemanticContextKind::Local;
  
      case DeclVisibilityKind::MemberOfCurrentNominal:
        return SemanticContextKind::CurrentNominal;
  
      case DeclVisibilityKind::MemberOfProtocolConformedToByCurrentNominal:
      case DeclVisibilityKind::MemberOfSuper:
        return SemanticContextKind::Super;
  
      case DeclVisibilityKind::MemberOfOutsideNominal:
        return SemanticContextKind::OutsideNominal;
  
      case DeclVisibilityKind::VisibleAtTopLevel:
        if (CurrDeclContext && D->getModuleContext() == CurrModule) {
          // Treat global variables from the same source file as local when
          // completing at top-level.
          if (isa<VarDecl>(D) && isTopLevelSubcontext(CurrDeclContext) &&
              D->getDeclContext()->getParentSourceFile() ==
                  CurrDeclContext->getParentSourceFile()) {
            return SemanticContextKind::Local;
          } else {
            return SemanticContextKind::CurrentModule;
          }
        } else {
          return SemanticContextKind::OtherModule;
        }
  
      case DeclVisibilityKind::DynamicLookup:
        switch (dynamicLookupInfo.getKind()) {
        case DynamicLookupInfo::None:
          llvm_unreachable("invalid DynamicLookupInfo::Kind for dynamic lookup");
  
        case DynamicLookupInfo::AnyObject:
          // AnyObject results can come from different modules, including the
          // current module, but we always assign them the OtherModule semantic
          // context.  These declarations are uniqued by signature, so it is
          // totally random (determined by the hash function) which of the
          // equivalent declarations (across multiple modules) we will get.
          return SemanticContextKind::OtherModule;
  
        case DynamicLookupInfo::KeyPathDynamicMember:
          // Use the visibility of the underlying declaration.
          // FIXME: KeyPath<AnyObject, U> !?!?
          assert(dynamicLookupInfo.getKeyPathDynamicMember().originalVisibility !=
                 DeclVisibilityKind::DynamicLookup);
          return getSemanticContext(
              D, dynamicLookupInfo.getKeyPathDynamicMember().originalVisibility,
              {});
        }
  
      case DeclVisibilityKind::MemberOfProtocolDerivedByCurrentNominal:
        llvm_unreachable("should not see this kind");
      }
      llvm_unreachable("unhandled kind");
    }
  
    bool isUnresolvedMemberIdealType(Type Ty) {
      assert(Ty);
      if (!IsUnresolvedMember)
        return false;
      Type idealTy = expectedTypeContext.idealType;
      if (!idealTy)
        return false;
      /// Consider optional object type is the ideal.
      /// For exmaple:
      ///   enum MyEnum { case foo, bar }
      ///   func foo(_: MyEnum?)
      ///   fooo(.<HERE>)
      /// Prefer '.foo' and '.bar' over '.some' and '.none'.
      idealTy = idealTy->lookThroughAllOptionalTypes();
      return idealTy->isEqual(Ty);
    }
  
    void addValueBaseName(CodeCompletionResultBuilder &Builder,
                          DeclBaseName Name) {
      auto NameStr = Name.userFacingName();
      bool shouldEscapeKeywords;
      if (Name.isSpecial()) {
        // Special names (i.e. 'init') are always displayed as its user facing
        // name.
        shouldEscapeKeywords = false;
      } else if (ExprType) {
        // After dot. User can write any keyword after '.' except for `init` and
        // `self`. E.g. 'func `init`()' must be called by 'expr.`init`()'.
        shouldEscapeKeywords = NameStr == "self" || NameStr == "init";
      } else {
        // As primary expresson. We have to escape almost every keywords except
        // for 'self' and 'Self'.
        shouldEscapeKeywords = NameStr != "self" && NameStr != "Self";
      }
  
      if (!shouldEscapeKeywords) {
        Builder.addBaseName(NameStr);
      } else {
        SmallString<16> buffer;
        Builder.addBaseName(Builder.escapeKeyword(NameStr, true, buffer));
      }
    }
  
    void addLeadingDot(CodeCompletionResultBuilder &Builder) {
      if (NeedOptionalUnwrap) {
        Builder.setNumBytesToErase(NumBytesToEraseForOptionalUnwrap);
        Builder.addQuestionMark();
        Builder.addLeadingDot();
        return;
      }
      if (needDot())
        Builder.addLeadingDot();
    }
  
    void addTypeAnnotation(CodeCompletionResultBuilder &Builder, Type T,
                           GenericSignature genericSig = GenericSignature()) {
      PrintOptions PO;
      PO.OpaqueReturnTypePrinting =
          PrintOptions::OpaqueReturnTypePrintingMode::WithoutOpaqueKeyword;
      if (auto typeContext = CurrDeclContext->getInnermostTypeContext())
        PO.setBaseType(typeContext->getDeclaredTypeInContext());
      Builder.addTypeAnnotation(eraseArchetypes(T, genericSig), PO);
      Builder.setExpectedTypeRelation(
          calculateMaxTypeRelation(T, expectedTypeContext, CurrDeclContext));
    }
  
    void addTypeAnnotationForImplicitlyUnwrappedOptional(
        CodeCompletionResultBuilder &Builder, Type T,
        GenericSignature genericSig = GenericSignature(),
        bool dynamicOrOptional = false) {
  
      std::string suffix;
      // FIXME: This retains previous behavior, but in reality the type of dynamic
      // lookups is IUO, not Optional as it is for the @optional attribute.
      if (dynamicOrOptional) {
        T = T->getOptionalObjectType();
        suffix = "?";
      }
  
      PrintOptions PO;
      PO.PrintOptionalAsImplicitlyUnwrapped = true;
      PO.OpaqueReturnTypePrinting =
          PrintOptions::OpaqueReturnTypePrintingMode::WithoutOpaqueKeyword;
      if (auto typeContext = CurrDeclContext->getInnermostTypeContext())
        PO.setBaseType(typeContext->getDeclaredTypeInContext());
      Builder.addTypeAnnotation(eraseArchetypes(T, genericSig), PO, suffix);
      Builder.setExpectedTypeRelation(
          calculateMaxTypeRelation(T, expectedTypeContext, CurrDeclContext));
    }
  
    /// For printing in code completion results, replace archetypes with
    /// protocol compositions.
    ///
    /// FIXME: Perhaps this should be an option in PrintOptions instead.
    Type eraseArchetypes(Type type, GenericSignature genericSig) {
      if (!genericSig)
        return type;
  
      auto buildProtocolComposition = [&](ArrayRef<ProtocolDecl *> protos) -> Type {
        SmallVector<Type, 2> types;
        for (auto proto : protos)
          types.push_back(proto->getDeclaredInterfaceType());
        return ProtocolCompositionType::get(Ctx, types,
                                            /*HasExplicitAnyObject=*/false);
      };
  
      if (auto *genericFuncType = type->getAs<GenericFunctionType>()) {
        SmallVector<AnyFunctionType::Param, 8> erasedParams;
        for (const auto &param : genericFuncType->getParams()) {
          auto erasedTy = eraseArchetypes(param.getPlainType(), genericSig);
          erasedParams.emplace_back(param.withType(erasedTy));
        }
        return GenericFunctionType::get(genericSig,
            erasedParams,
            eraseArchetypes(genericFuncType->getResult(), genericSig),
            genericFuncType->getExtInfo());
      }
  
      return type.transform([&](Type t) -> Type {
        // FIXME: Code completion should only deal with one or the other,
        // and not both.
        if (auto *archetypeType = t->getAs<ArchetypeType>()) {
          // Don't erase opaque archetype.
          if (isa<OpaqueTypeArchetypeType>(archetypeType))
            return t;
  
          auto protos = archetypeType->getConformsTo();
          if (!protos.empty())
            return buildProtocolComposition(protos);
        }
  
        if (t->isTypeParameter()) {
          const auto protos = genericSig->getRequiredProtocols(t);
          if (!protos.empty())
            return buildProtocolComposition(protos);
        }
  
        return t;
      });
    }
  
    Type getTypeOfMember(const ValueDecl *VD,
                         DynamicLookupInfo dynamicLookupInfo) {
      switch (dynamicLookupInfo.getKind()) {
      case DynamicLookupInfo::None:
        return getTypeOfMember(VD, this->ExprType);
      case DynamicLookupInfo::AnyObject:
        return getTypeOfMember(VD, Type());
      case DynamicLookupInfo::KeyPathDynamicMember: {
        auto &keyPathInfo = dynamicLookupInfo.getKeyPathDynamicMember();
  
        // Map the result of VD to keypath member lookup results.
        // Given:
        //   struct Wrapper<T> {
        //     subscript<U>(dynamicMember: KeyPath<T, U>) -> Wrapped<U> { get }
        //   }
        //   struct Circle {
        //     var center: Point { get }
        //     var radius: Length { get }
        //   }
        //
        // Consider 'Wrapper<Circle>.center'.
        //   'VD' is 'Circle.center' decl.
        //   'keyPathInfo.subscript' is 'Wrapper<T>.subscript' decl.
        //   'keyPathInfo.baseType' is 'Wrapper<Circle>' type.
  
        // FIXME: Handle nested keypath member lookup.
        // i.e. cases where 'ExprType' != 'keyPathInfo.baseType'.
  
        auto *SD = keyPathInfo.subscript;
        const auto elementTy = SD->getElementInterfaceType();
        if (!elementTy->hasTypeParameter())
          return elementTy;
  
        // Map is:
        //   { τ_0_0(T) => Circle
        //     τ_1_0(U) => U }
        auto subs = keyPathInfo.baseType->getMemberSubstitutions(SD);
  
        // If the keyPath result type has type parameters, that might affect the
        // subscript result type.
        auto keyPathResultTy = getResultTypeOfKeypathDynamicMember(SD)->
          mapTypeOutOfContext();
        if (keyPathResultTy->hasTypeParameter()) {
          auto keyPathRootTy = getRootTypeOfKeypathDynamicMember(SD).
            subst(QueryTypeSubstitutionMap{subs},
                  LookUpConformanceInModule(CurrModule));
  
          // The result type of the VD.
          // i.e. 'Circle.center' => 'Point'.
          auto innerResultTy = getTypeOfMember(VD, keyPathRootTy);
  
          if (auto paramTy = keyPathResultTy->getAs<GenericTypeParamType>()) {
            // Replace keyPath result type in the map with the inner result type.
            // i.e. Make the map as:
            //   { τ_0_0(T) => Circle
            //     τ_1_0(U) => Point }
            auto key =
                paramTy->getCanonicalType()->castTo<GenericTypeParamType>();
            subs[key] = innerResultTy;
          } else {
            // FIXME: Handle the case where the KeyPath result is generic.
            // e.g. 'subscript<U>(dynamicMember: KeyPath<T, Box<U>>) -> Bag<U>'
            // For now, just return the inner type.
            return innerResultTy;
          }
        }
  
        // Substitute the element type of the subscript using modified map.
        // i.e. 'Wrapped<U>' => 'Wrapped<Point>'.
        return elementTy.subst(QueryTypeSubstitutionMap{subs},
                               LookUpConformanceInModule(CurrModule));
      }
      }
      llvm_unreachable("Unhandled DynamicLookupInfo Kind in switch");
    }
  
    Type getTypeOfMember(const ValueDecl *VD, Type ExprType) {
      Type T = VD->getInterfaceType();
      assert(!T.isNull());
  
      if (ExprType) {
        Type ContextTy = VD->getDeclContext()->getDeclaredInterfaceType();
        if (ContextTy) {
          // Look through lvalue types and metatypes
          Type MaybeNominalType = ExprType->getRValueType();
  
          if (auto Metatype = MaybeNominalType->getAs<MetatypeType>())
            MaybeNominalType = Metatype->getInstanceType();
  
          if (auto SelfType = MaybeNominalType->getAs<DynamicSelfType>())
            MaybeNominalType = SelfType->getSelfType();
  
          // For optional protocol requirements and dynamic dispatch,
          // strip off optionality from the base type, but only if
          // we're not actually completing a member of Optional.
          if (!ContextTy->getOptionalObjectType() &&
              MaybeNominalType->getOptionalObjectType())
            MaybeNominalType = MaybeNominalType->getOptionalObjectType();
  
          // For dynamic lookup don't substitute in the base type.
          if (MaybeNominalType->isAnyObject())
            return T;
  
          // FIXME: Sometimes ExprType is the type of the member here,
          // and not the type of the base. That is inconsistent and
          // should be cleaned up.
          if (!MaybeNominalType->mayHaveMembers())
            return T;
  
          // We can't do anything if the base type has unbound generic parameters.
          if (MaybeNominalType->hasUnboundGenericType())
            return T;
  
          // For everything else, substitute in the base type.
          auto Subs = MaybeNominalType->getMemberSubstitutionMap(CurrModule, VD);
  
          // For a GenericFunctionType, we only want to substitute the
          // param/result types, as otherwise we might end up with a bad generic
          // signature if there are UnresolvedTypes present in the base type. Note
          // we pass in DesugarMemberTypes so that we see the actual concrete type
          // witnesses instead of type alias types.
          if (auto *GFT = T->getAs<GenericFunctionType>()) {
            T = GFT->substGenericArgs(Subs, SubstFlags::DesugarMemberTypes);
          } else {
            T = T.subst(Subs, SubstFlags::DesugarMemberTypes);
          }
        }
      }
  
      return T;
    }
  
    Type getAssociatedTypeType(const AssociatedTypeDecl *ATD) {
      Type BaseTy = BaseType;
      if (!BaseTy)
        BaseTy = ExprType;
      if (!BaseTy && CurrDeclContext)
        BaseTy = CurrDeclContext->getInnermostTypeContext()
                     ->getDeclaredTypeInContext();
      if (BaseTy) {
        BaseTy = BaseTy->getInOutObjectType()->getMetatypeInstanceType();
        if (auto NTD = BaseTy->getAnyNominal()) {
          auto *Module = NTD->getParentModule();
          auto Conformance = Module->lookupConformance(
              BaseTy, ATD->getProtocol());
          if (Conformance.isConcrete()) {
            return Conformance.getConcrete()->getTypeWitness(
                const_cast<AssociatedTypeDecl *>(ATD));
          }
        }
      }
      return Type();
    }
  
    void analyzeActorIsolation(const ValueDecl *VD, Type T, bool &implicitlyAsync,
                               Optional<NotRecommendedReason> &NotRecommended) {
      auto isolation = getActorIsolation(const_cast<ValueDecl *>(VD));
  
      switch (isolation.getKind()) {
      case ActorIsolation::DistributedActorInstance: {
        // TODO: implicitlyThrowing here for distributed
        LLVM_FALLTHROUGH; // continue the ActorInstance checks
      }
      case ActorIsolation::ActorInstance: {
        if (IsCrossActorReference) {
          implicitlyAsync = true;
          // TODO: 'NotRecommended' if this is a r-value reference.
        }
        break;
      }
      case ActorIsolation::GlobalActorUnsafe:
        // For "unsafe" global actor isolation, automatic 'async' only happens
        // if the context has adopted concurrency.
        if (!CanCurrDeclContextHandleAsync &&
            !completionContextUsesConcurrencyFeatures(CurrDeclContext) &&
            !CurrDeclContext->getParentModule()->isConcurrencyChecked()) {
          return;
        }
        LLVM_FALLTHROUGH;
      case ActorIsolation::GlobalActor: {
        auto contextIsolation = getActorIsolationOfContext(
            const_cast<DeclContext *>(CurrDeclContext));
        if (contextIsolation != isolation) {
          implicitlyAsync = true;
        }
        break;
      }
      case ActorIsolation::Unspecified:
      case ActorIsolation::Independent:
        return;
      }
  
      // If the reference is 'async', all types must be 'Sendable'.
      if (CurrDeclContext->getParentModule()->isConcurrencyChecked() &&
          implicitlyAsync && T) {
        auto *M = CurrDeclContext->getParentModule();
        if (isa<VarDecl>(VD)) {
          if (!isSendableType(M, T)) {
            NotRecommended = NotRecommendedReason::CrossActorReference;
          }
        } else {
          assert(isa<FuncDecl>(VD) || isa<SubscriptDecl>(VD));
          // Check if the result and the param types are all 'Sendable'.
          auto *AFT = T->castTo<AnyFunctionType>();
          if (!isSendableType(M, AFT->getResult())) {
            NotRecommended = NotRecommendedReason::CrossActorReference;
          } else {
            for (auto &param : AFT->getParams()) {
              Type paramType = param.getPlainType();
              if (!isSendableType(M, paramType)) {
                NotRecommended = NotRecommendedReason::CrossActorReference;
                break;
              }
            }
          }
        }
      }
    }
  
    void addVarDeclRef(const VarDecl *VD, DeclVisibilityKind Reason,
                       DynamicLookupInfo dynamicLookupInfo) {
      if (!VD->hasName())
        return;
  
      const Identifier Name = VD->getName();
      assert(!Name.empty() && "name should not be empty");
  
      Type VarType;
      if (VD->hasInterfaceType())
        VarType = getTypeOfMember(VD, dynamicLookupInfo);
  
      Optional<NotRecommendedReason> NotRecommended;
      // "not recommended" in its own getter.
      if (Kind == LookupKind::ValueInDeclContext) {
        if (auto accessor = dyn_cast<AccessorDecl>(CurrDeclContext)) {
          if (accessor->getStorage() == VD && accessor->isGetter())
            NotRecommended = NotRecommendedReason::VariableUsedInOwnDefinition;
        }
      }
      bool implicitlyAsync = false;
      analyzeActorIsolation(VD, VarType, implicitlyAsync, NotRecommended);
      if (!isForCaching() && !NotRecommended && implicitlyAsync &&
          !CanCurrDeclContextHandleAsync) {
        NotRecommended = NotRecommendedReason::InvalidAsyncContext;
      }
  
      CodeCompletionResultBuilder Builder(
          Sink, CodeCompletionResult::ResultKind::Declaration,
          getSemanticContext(VD, Reason, dynamicLookupInfo), expectedTypeContext);
      Builder.setAssociatedDecl(VD);
      addLeadingDot(Builder);
      addValueBaseName(Builder, Name);
  
      if (NotRecommended)
        Builder.setNotRecommended(*NotRecommended);
  
      if (!VarType)
        return;
  
      if (auto *PD = dyn_cast<ParamDecl>(VD)) {
        if (Name != Ctx.Id_self && PD->isInOut()) {
          // It is useful to show inout for function parameters.
          // But for 'self' it is just noise.
          VarType = InOutType::get(VarType);
        }
      }
      auto DynamicOrOptional =
          IsDynamicLookup || VD->getAttrs().hasAttribute<OptionalAttr>();
      if (DynamicOrOptional) {
        // Values of properties that were found on a AnyObject have
        // Optional<T> type.  Same applies to optional members.
        VarType = OptionalType::get(VarType);
      }
  
      auto genericSig =
          VD->getInnermostDeclContext()->getGenericSignatureOfContext();
      if (VD->isImplicitlyUnwrappedOptional())
        addTypeAnnotationForImplicitlyUnwrappedOptional(
            Builder, VarType, genericSig, DynamicOrOptional);
      else
        addTypeAnnotation(Builder, VarType, genericSig);
  
      if (implicitlyAsync)
        Builder.addAnnotatedAsync();
  
      if (isUnresolvedMemberIdealType(VarType))
        Builder.addFlair(CodeCompletionFlairBit::ExpressionSpecific);
    }
  
    static bool hasInterestingDefaultValues(const AbstractFunctionDecl *func) {
      if (!func) return false;
  
      for (auto param : *func->getParameters()) {
        switch (param->getDefaultArgumentKind()) {
        case DefaultArgumentKind::Normal:
        case DefaultArgumentKind::StoredProperty:
        case DefaultArgumentKind::Inherited: // FIXME: include this?
          return true;
        default:
          break;
        }
      }
      return false;
    }
  
    /// Build argument patterns for calling. Returns \c true if any content was
    /// added to \p Builder. If \p declParams is non-empty, the size must match
    /// with \p typeParams.
    bool addCallArgumentPatterns(CodeCompletionResultBuilder &Builder,
                                 ArrayRef<AnyFunctionType::Param> typeParams,
                                 ArrayRef<const ParamDecl *> declParams,
                                 GenericSignature genericSig,
                                 bool includeDefaultArgs = true) {
      assert(declParams.empty() || typeParams.size() == declParams.size());
  
      bool modifiedBuilder = false;
  
      // Determine whether we should skip this argument because it is defaulted.
      auto shouldSkipArg = [&](const ParamDecl *PD) -> bool {
        switch (PD->getDefaultArgumentKind()) {
        case DefaultArgumentKind::None:
          return false;
  
        case DefaultArgumentKind::Normal:
        case DefaultArgumentKind::StoredProperty:
        case DefaultArgumentKind::Inherited:
        case DefaultArgumentKind::NilLiteral:
        case DefaultArgumentKind::EmptyArray:
        case DefaultArgumentKind::EmptyDictionary:
          return !includeDefaultArgs;
  
  #define MAGIC_IDENTIFIER(NAME, STRING, SYNTAX_KIND) \
        case DefaultArgumentKind::NAME:
  #include "swift/AST/MagicIdentifierKinds.def"
          // Skip parameters that are defaulted to source location or other
          // caller context information.  Users typically don't want to specify
          // these parameters.
          return true;
        }
  
        llvm_unreachable("Unhandled DefaultArgumentKind in switch.");
      };
  
      bool NeedComma = false;
      // Iterate over each parameter.
      for (unsigned i = 0; i != typeParams.size(); ++i) {
        auto &typeParam = typeParams[i];
  
        Identifier argName;
        Identifier bodyName;
        bool isIUO = false;
  
        if (!declParams.empty()) {
          auto *PD = declParams[i];
          if (shouldSkipArg(PD))
            continue;
          argName = PD->getArgumentName();
          bodyName = PD->getParameterName();
          isIUO = PD->isImplicitlyUnwrappedOptional();
        } else {
          isIUO = false;
          argName = typeParam.getLabel();
        }
  
        bool isVariadic = typeParam.isVariadic();
        bool isInOut = typeParam.isInOut();
        bool isAutoclosure = typeParam.isAutoClosure();
        Type paramTy = typeParam.getPlainType();
        if (isVariadic)
          paramTy = ParamDecl::getVarargBaseTy(paramTy);
  
        if (NeedComma)
          Builder.addComma();
        Type contextTy;
        if (auto typeContext = CurrDeclContext->getInnermostTypeContext())
          contextTy = typeContext->getDeclaredTypeInContext();
  
        Builder.addCallArgument(argName, bodyName,
                                eraseArchetypes(paramTy, genericSig), contextTy,
                                isVariadic, isInOut, isIUO, isAutoclosure,
                                /*useUnderscoreLabel=*/false,
                                /*isLabeledTrailingClosure=*/false);
  
        modifiedBuilder = true;
        NeedComma = true;
      }
      return modifiedBuilder;
    }
  
    /// Build argument patterns for calling. Returns \c true if any content was
    /// added to \p Builder. If \p Params is non-nullptr, \F
    bool addCallArgumentPatterns(CodeCompletionResultBuilder &Builder,
                                 const AnyFunctionType *AFT,
                                 const ParameterList *Params,
                                 GenericSignature genericSig,
                                 bool includeDefaultArgs = true) {
      ArrayRef<const ParamDecl *> declParams;
      if (Params)
        declParams = Params->getArray();
      return addCallArgumentPatterns(Builder, AFT->getParams(), declParams,
                                     genericSig, includeDefaultArgs);
    }
  
    static void addEffectsSpecifiers(CodeCompletionResultBuilder &Builder,
                               const AnyFunctionType *AFT,
                               const AbstractFunctionDecl *AFD,
                               bool forceAsync = false) {
      assert(AFT != nullptr);
  
      // 'async'.
      if (forceAsync || (AFD && AFD->hasAsync()) || AFT->isAsync())
        Builder.addAnnotatedAsync();
  
      // 'throws' or 'rethrows'.
      if (AFD && AFD->getAttrs().hasAttribute<RethrowsAttr>())
        Builder.addAnnotatedRethrows();
      else if (AFT->isThrowing())
        Builder.addAnnotatedThrows();
    }
  
    void addPoundAvailable(Optional<StmtKind> ParentKind) {
      if (ParentKind != StmtKind::If && ParentKind != StmtKind::Guard)
        return;
      CodeCompletionResultBuilder Builder(Sink, CodeCompletionResult::ResultKind::Keyword,
        // FIXME: SemanticContextKind::Local is not correct.
        // Use 'None' (and fix prioritization) or introduce a new context.
        SemanticContextKind::Local, expectedTypeContext);
      Builder.addFlair(CodeCompletionFlairBit::ExpressionSpecific);
      Builder.addBaseName("available");
      Builder.addLeftParen();
      Builder.addSimpleTypedParameter("Platform", /*IsVarArg=*/true);
      Builder.addComma();
      Builder.addTextChunk("*");
      Builder.addRightParen();
    }
  
    void addPoundSelector(bool needPound) {
      // #selector is only available when the Objective-C runtime is.
      if (!Ctx.LangOpts.EnableObjCInterop) return;
  
      CodeCompletionResultBuilder Builder(
          Sink, CodeCompletionResult::ResultKind::Keyword,
          SemanticContextKind::None, {});
      if (needPound)
        Builder.addTextChunk("#selector");
      else
        Builder.addTextChunk("selector");
      Builder.addLeftParen();
      Builder.addSimpleTypedParameter("@objc method", /*IsVarArg=*/false);
      Builder.addRightParen();
      Builder.addTypeAnnotation("Selector");
      // This function is called only if the context type is 'Selector'.
      Builder.setExpectedTypeRelation(
          CodeCompletionResult::ExpectedTypeRelation::Identical);
    }
  
    void addPoundKeyPath(bool needPound) {
      // #keyPath is only available when the Objective-C runtime is.
      if (!Ctx.LangOpts.EnableObjCInterop) return;
  
      CodeCompletionResultBuilder Builder(
          Sink, CodeCompletionResult::ResultKind::Keyword,
          SemanticContextKind::None, {});
      if (needPound)
        Builder.addTextChunk("#keyPath");
      else
        Builder.addTextChunk("keyPath");
      Builder.addLeftParen();
      Builder.addSimpleTypedParameter("@objc property sequence",
                                      /*IsVarArg=*/false);
      Builder.addRightParen();
      Builder.addTypeAnnotation("String");
      // This function is called only if the context type is 'String'.
      Builder.setExpectedTypeRelation(
          CodeCompletionResult::ExpectedTypeRelation::Identical);
    }
  
    SemanticContextKind getSemanticContextKind(const ValueDecl *VD) {
      // FIXME: to get the corect semantic context we need to know how lookup
      // would have found the VD. For now, just infer a reasonable semantics.
  
      if (!VD)
        return SemanticContextKind::CurrentModule;
  
      DeclContext *calleeDC = VD->getDeclContext();
      
      if (calleeDC->isTypeContext())
        // FIXME: We should distinguish CurrentNominal and Super. We need to
        // propagate the base type to do that.
        return SemanticContextKind::CurrentNominal;
  
      if (calleeDC->isLocalContext())
        return SemanticContextKind::Local;
      if (calleeDC->getParentModule() == CurrModule)
        return SemanticContextKind::CurrentModule;
  
      return SemanticContextKind::OtherModule;
    }
  
    void addSubscriptCallPattern(
        const AnyFunctionType *AFT, const SubscriptDecl *SD,
        const Optional<SemanticContextKind> SemanticContext = None) {
      foundFunction(AFT);
      GenericSignature genericSig;
      if (SD)
        genericSig = SD->getGenericSignatureOfContext();
  
      CodeCompletionResultBuilder Builder(
          Sink,
          SD ? CodeCompletionResult::ResultKind::Declaration
             : CodeCompletionResult::ResultKind::Pattern,
          SemanticContext ? *SemanticContext : getSemanticContextKind(SD),
          expectedTypeContext);
      if (SD)
        Builder.setAssociatedDecl(SD);
      if (!HaveLParen) {
        Builder.addLeftBracket();
      } else {
        // Add 'ArgumentLabels' only if it has '['. Without existing '[',
        // consider it suggesting 'subscript' itself, not call arguments for it.
        Builder.addFlair(CodeCompletionFlairBit::ArgumentLabels);
        Builder.addAnnotatedLeftBracket();
      }
      ArrayRef<const ParamDecl *> declParams;
      if (SD)
        declParams = SD->getIndices()->getArray();
      addCallArgumentPatterns(Builder, AFT->getParams(), declParams, genericSig);
      if (!HaveLParen)
        Builder.addRightBracket();
      else
        Builder.addAnnotatedRightBracket();
      if (SD && SD->isImplicitlyUnwrappedOptional())
        addTypeAnnotationForImplicitlyUnwrappedOptional(Builder,
                                                        AFT->getResult(),
                                                        genericSig);
      else
        addTypeAnnotation(Builder, AFT->getResult(), genericSig);
    }
  
    void addFunctionCallPattern(
        const AnyFunctionType *AFT, const AbstractFunctionDecl *AFD = nullptr,
        const Optional<SemanticContextKind> SemanticContext = None) {
      GenericSignature genericSig;
      if (AFD)
        genericSig = AFD->getGenericSignatureOfContext();
  
      // Add the pattern, possibly including any default arguments.
      auto addPattern = [&](ArrayRef<const ParamDecl *> declParams = {},
                            bool includeDefaultArgs = true) {
        CodeCompletionResultBuilder Builder(
            Sink,
            AFD ? CodeCompletionResult::ResultKind::Declaration
                : CodeCompletionResult::ResultKind::Pattern,
            SemanticContext ? *SemanticContext : getSemanticContextKind(AFD),
            expectedTypeContext);
        Builder.addFlair(CodeCompletionFlairBit::ArgumentLabels);
        if (AFD)
          Builder.setAssociatedDecl(AFD);
  
        if (!HaveLParen)
          Builder.addLeftParen();
        else
          Builder.addAnnotatedLeftParen();
  
        addCallArgumentPatterns(Builder, AFT->getParams(), declParams,
                                genericSig, includeDefaultArgs);
  
        // The rparen matches the lparen here so that we insert both or neither.
        if (!HaveLParen)
          Builder.addRightParen();
        else
          Builder.addAnnotatedRightParen();
  
        addEffectsSpecifiers(Builder, AFT, AFD);
  
        if (AFD &&
            AFD->isImplicitlyUnwrappedOptional())
          addTypeAnnotationForImplicitlyUnwrappedOptional(Builder,
                                                          AFT->getResult(),
                                                          genericSig);
        else
          addTypeAnnotation(Builder, AFT->getResult(), genericSig);
  
        if (!isForCaching() && AFT->isAsync() && !CanCurrDeclContextHandleAsync) {
          Builder.setNotRecommended(NotRecommendedReason::InvalidAsyncContext);
        }
      };
  
      if (!AFD || !AFD->getInterfaceType()->is<AnyFunctionType>()) {
        // Probably, calling closure type expression.
        foundFunction(AFT);
        addPattern();
        return;
      } else {
        // Calling function or method.
        foundFunction(AFD);
  
        // FIXME: Hack because we don't know we are calling instance
        // method or not. There's invariant that funcTy is derived from AFD.
        // Only if we are calling instance method on meta type, AFT is still
        // curried. So we should be able to detect that by comparing curried level
        // of AFT and the interface type of AFD.
        auto getCurriedLevel = [](const AnyFunctionType *funcTy) -> unsigned {
          unsigned level = 0;
          while ((funcTy = funcTy->getResult()->getAs<AnyFunctionType>()))
            ++level;
          return level;
        };
        bool isImplicitlyCurriedInstanceMethod =
            (AFD->hasImplicitSelfDecl() &&
             getCurriedLevel(AFT) ==
                 getCurriedLevel(
                     AFD->getInterfaceType()->castTo<AnyFunctionType>()) &&
             // NOTE: shouldn't be necessary, but just in case curried level check
             // is insufficient.
             AFT->getParams().size() == 1 &&
             AFT->getParams()[0].getLabel().empty());
  
        if (isImplicitlyCurriedInstanceMethod) {
          addPattern({AFD->getImplicitSelfDecl()}, /*includeDefaultArgs=*/true);
        } else {
          if (hasInterestingDefaultValues(AFD))
            addPattern(AFD->getParameters()->getArray(),
                       /*includeDefaultArgs=*/false);
          addPattern(AFD->getParameters()->getArray(),
                     /*includeDefaultArgs=*/true);
        }
      }
    }
  
    bool isImplicitlyCurriedInstanceMethod(const AbstractFunctionDecl *FD) {
      if (FD->isStatic())
        return false;
  
      switch (Kind) {
      case LookupKind::ValueExpr:
        return ExprType->is<AnyMetatypeType>();
      case LookupKind::ValueInDeclContext:
        if (InsideStaticMethod)
          return FD->getDeclContext() == CurrentMethod->getDeclContext();
        if (auto Init = dyn_cast<Initializer>(CurrDeclContext)) {
          if (auto PatInit = dyn_cast<PatternBindingInitializer>(Init)) {
            if (PatInit->getInitializedLazyVar())
              return false;
          }
          return FD->getDeclContext() == Init->getInnermostTypeContext();
        }
        return false;
      case LookupKind::EnumElement:
      case LookupKind::Type:
      case LookupKind::TypeInDeclContext:
      case LookupKind::GenericRequirement:
        llvm_unreachable("cannot have a method call while doing a "
                         "type completion");
      case LookupKind::ImportFromModule:
        return false;
      }
  
      llvm_unreachable("Unhandled LookupKind in switch.");
    }
  
    void addMethodCall(const FuncDecl *FD, DeclVisibilityKind Reason,
                       DynamicLookupInfo dynamicLookupInfo) {
      if (FD->getBaseIdentifier().empty())
        return;
      foundFunction(FD);
  
      const Identifier Name = FD->getBaseIdentifier();
      assert(!Name.empty() && "name should not be empty");
  
      Type FunctionType = getTypeOfMember(FD, dynamicLookupInfo);
      assert(FunctionType);
  
      auto AFT = FunctionType->getAs<AnyFunctionType>();
  
      bool IsImplicitlyCurriedInstanceMethod = false;
      if (FD->hasImplicitSelfDecl()) {
        IsImplicitlyCurriedInstanceMethod = isImplicitlyCurriedInstanceMethod(FD);
  
        // Strip off '(_ self: Self)' if needed.
        if (AFT && !IsImplicitlyCurriedInstanceMethod) {
          AFT = AFT->getResult()->getAs<AnyFunctionType>();
  
          // Check for duplicates with the adjusted type too.
          if (isDuplicate(FD, AFT))
            return;
        }
      }
  
      bool trivialTrailingClosure = false;
      if (AFT && !IsImplicitlyCurriedInstanceMethod)
        trivialTrailingClosure = hasTrivialTrailingClosure(FD, AFT);
  
      Optional<NotRecommendedReason> NotRecommended;
      bool implictlyAsync = false;
      analyzeActorIsolation(FD, AFT, implictlyAsync, NotRecommended);
  
      if (!isForCaching() && !NotRecommended &&
          !IsImplicitlyCurriedInstanceMethod &&
          ((AFT && AFT->isAsync()) || implictlyAsync) &&
          !CanCurrDeclContextHandleAsync) {
        NotRecommended = NotRecommendedReason::InvalidAsyncContext;
      }
  
      // Add the method, possibly including any default arguments.
      auto addMethodImpl = [&](bool includeDefaultArgs = true,
                               bool trivialTrailingClosure = false) {
        CodeCompletionResultBuilder Builder(
            Sink, CodeCompletionResult::ResultKind::Declaration,
            getSemanticContext(FD, Reason, dynamicLookupInfo),
            expectedTypeContext);
        Builder.setAssociatedDecl(FD);
  
        if (IsSuperRefExpr && CurrentMethod &&
            CurrentMethod->getOverriddenDecl() == FD)
          Builder.addFlair(CodeCompletionFlairBit::SuperChain);
  
        if (NotRecommended)
          Builder.setNotRecommended(*NotRecommended);
  
        addLeadingDot(Builder);
        addValueBaseName(Builder, Name);
        if (IsDynamicLookup)
          Builder.addDynamicLookupMethodCallTail();
        else if (FD->getAttrs().hasAttribute<OptionalAttr>())
          Builder.addOptionalMethodCallTail();
  
        if (!AFT) {
          addTypeAnnotation(Builder, FunctionType,
                            FD->getGenericSignatureOfContext());
          return;
        }
        if (IsImplicitlyCurriedInstanceMethod) {
          Builder.addLeftParen();
          addCallArgumentPatterns(Builder, AFT->getParams(),
                                  {FD->getImplicitSelfDecl()},
                                  FD->getGenericSignatureOfContext(),
                                  includeDefaultArgs);
          Builder.addRightParen();
        } else if (trivialTrailingClosure) {
          Builder.addBraceStmtWithCursor(" { code }");
          addEffectsSpecifiers(Builder, AFT, FD, implictlyAsync);
        } else {
          Builder.addLeftParen();
          addCallArgumentPatterns(Builder, AFT, FD->getParameters(),
                                  FD->getGenericSignatureOfContext(),
                                  includeDefaultArgs);
          Builder.addRightParen();
          addEffectsSpecifiers(Builder, AFT, FD, implictlyAsync);
        }
  
        // Build type annotation.
        Type ResultType = AFT->getResult();
        // As we did with parameters in addParamPatternFromFunction,
        // for regular methods we'll print '!' after implicitly
        // unwrapped optional results.
        bool IsIUO =
            !IsImplicitlyCurriedInstanceMethod &&
            FD->isImplicitlyUnwrappedOptional();
  
        PrintOptions PO;
        PO.OpaqueReturnTypePrinting =
            PrintOptions::OpaqueReturnTypePrintingMode::WithoutOpaqueKeyword;
        PO.PrintOptionalAsImplicitlyUnwrapped = IsIUO;
        if (auto typeContext = CurrDeclContext->getInnermostTypeContext())
          PO.setBaseType(typeContext->getDeclaredTypeInContext());
        Type AnnotationTy =
            eraseArchetypes(ResultType, FD->getGenericSignatureOfContext());
        if (Builder.shouldAnnotateResults()) {
          Builder.withNestedGroup(
              CodeCompletionString::Chunk::ChunkKind::TypeAnnotationBegin, [&] {
                CodeCompletionStringPrinter printer(Builder);
                auto TL = TypeLoc::withoutLoc(AnnotationTy);
                printer.printTypePre(TL);
                if (IsImplicitlyCurriedInstanceMethod) {
                  auto *FnType = AnnotationTy->castTo<AnyFunctionType>();
                  AnyFunctionType::printParams(FnType->getParams(), printer,
                                               PrintOptions());
                  AnnotationTy = FnType->getResult();
                  printer.printText(" -> ");
                }
  
                // What's left is the result type.
                if (AnnotationTy->isVoid())
                  AnnotationTy = Ctx.getVoidDecl()->getDeclaredInterfaceType();
                AnnotationTy.print(printer, PO);
                printer.printTypePost(TL);
              });
        } else {
          llvm::SmallString<32> TypeStr;
          llvm::raw_svector_ostream OS(TypeStr);
          if (IsImplicitlyCurriedInstanceMethod) {
            auto *FnType = AnnotationTy->castTo<AnyFunctionType>();
            AnyFunctionType::printParams(FnType->getParams(), OS);
            AnnotationTy = FnType->getResult();
            OS << " -> ";
          }
  
          // What's left is the result type.
          if (AnnotationTy->isVoid())
            AnnotationTy = Ctx.getVoidDecl()->getDeclaredInterfaceType();
          AnnotationTy.print(OS, PO);
          Builder.addTypeAnnotation(TypeStr);
        }
  
        Builder.setExpectedTypeRelation(calculateMaxTypeRelation(
            ResultType, expectedTypeContext, CurrDeclContext));
  
        if (isUnresolvedMemberIdealType(ResultType))
          Builder.addFlair(CodeCompletionFlairBit::ExpressionSpecific);
  
        if (!IsImplicitlyCurriedInstanceMethod &&
            expectedTypeContext.requiresNonVoid() &&
            ResultType->isVoid()) {
          Builder.setExpectedTypeRelation(CodeCompletionResult::Invalid);
        }
      };
  
      if (!AFT || IsImplicitlyCurriedInstanceMethod) {
        addMethodImpl();
      } else {
        if (trivialTrailingClosure)
          addMethodImpl(/*includeDefaultArgs=*/false,
                        /*trivialTrailingClosure=*/true);
        if (hasInterestingDefaultValues(FD))
          addMethodImpl(/*includeDefaultArgs=*/false);
        addMethodImpl(/*includeDefaultArgs=*/true);
      }
    }
  
    void addConstructorCall(const ConstructorDecl *CD, DeclVisibilityKind Reason,
                            DynamicLookupInfo dynamicLookupInfo,
                            Optional<Type> BaseType, Optional<Type> Result,
                            bool IsOnType = true,
                            Identifier addName = Identifier()) {
      foundFunction(CD);
      Type MemberType = getTypeOfMember(CD, BaseType.getValueOr(ExprType));
      AnyFunctionType *ConstructorType = nullptr;
      if (auto MemberFuncType = MemberType->getAs<AnyFunctionType>())
        ConstructorType = MemberFuncType->getResult()
                                        ->castTo<AnyFunctionType>();
  
      bool needInit = false;
      if (!IsOnType) {
        assert(addName.empty());
        needInit = true;
      } else if (addName.empty() && HaveDot) {
        needInit = true;
      }
  
      // If we won't be able to provide a result, bail out.
      if (!ConstructorType && addName.empty() && !needInit)
        return;
  
      // Add the constructor, possibly including any default arguments.
      auto addConstructorImpl = [&](bool includeDefaultArgs = true) {
        CodeCompletionResultBuilder Builder(
            Sink, CodeCompletionResult::ResultKind::Declaration,
            getSemanticContext(CD, Reason, dynamicLookupInfo),
            expectedTypeContext);
        Builder.setAssociatedDecl(CD);
  
        if (IsSuperRefExpr && CurrentMethod &&
            CurrentMethod->getOverriddenDecl() == CD)
          Builder.addFlair(CodeCompletionFlairBit::SuperChain);
  
        if (needInit) {
          assert(addName.empty());
          addLeadingDot(Builder);
          Builder.addBaseName("init");
        } else if (!addName.empty()) {
          Builder.addBaseName(addName.str());
        } else {
          Builder.addFlair(CodeCompletionFlairBit::ArgumentLabels);
        }
  
        if (!ConstructorType) {
          addTypeAnnotation(Builder, MemberType,
                            CD->getGenericSignatureOfContext());
          return;
        }
  
        if (!HaveLParen)
          Builder.addLeftParen();
        else
          Builder.addAnnotatedLeftParen();
  
        addCallArgumentPatterns(Builder, ConstructorType, CD->getParameters(),
                                CD->getGenericSignatureOfContext(),
                                includeDefaultArgs);
  
        // The rparen matches the lparen here so that we insert both or neither.
        if (!HaveLParen)
          Builder.addRightParen();
        else
          Builder.addAnnotatedRightParen();
  
        addEffectsSpecifiers(Builder, ConstructorType, CD);
  
        if (!Result.hasValue())
          Result = ConstructorType->getResult();
        if (CD->isImplicitlyUnwrappedOptional()) {
          addTypeAnnotationForImplicitlyUnwrappedOptional(
              Builder, *Result, CD->getGenericSignatureOfContext());
        } else {
          addTypeAnnotation(Builder, *Result, CD->getGenericSignatureOfContext());
        }
  
        if (!isForCaching() && ConstructorType->isAsync() &&
            !CanCurrDeclContextHandleAsync) {
          Builder.setNotRecommended(NotRecommendedReason::InvalidAsyncContext);
        }
      };
  
      if (ConstructorType && hasInterestingDefaultValues(CD))
        addConstructorImpl(/*includeDefaultArgs*/ false);
      addConstructorImpl();
    }
  
    void addConstructorCallsForType(Type type, Identifier name,
                                    DeclVisibilityKind Reason,
                                    DynamicLookupInfo dynamicLookupInfo) {
      if (!Sink.addInitsToTopLevel)
        return;
  
      assert(CurrDeclContext);
  
      auto results =
          swift::lookupSemanticMember(const_cast<DeclContext *>(CurrDeclContext),
                                      type, DeclBaseName::createConstructor());
      for (const auto &entry : results.allResults()) {
        auto *init = cast<ConstructorDecl>(entry.getValueDecl());
        if (init->shouldHideFromEditor())
          continue;
        addConstructorCall(cast<ConstructorDecl>(init), Reason,
                           dynamicLookupInfo, type, None,
                           /*IsOnType=*/true, name);
      }
    }
  
    void addSubscriptCall(const SubscriptDecl *SD, DeclVisibilityKind Reason,
                          DynamicLookupInfo dynamicLookupInfo) {
      // Don't add subscript call to unqualified completion.
      if (!ExprType)
        return;
  
      // Subscript after '.' is valid only after type part of Swift keypath
      // expression. (e.g. '\TyName.SubTy.[0])
      if (HaveDot && !IsAfterSwiftKeyPathRoot)
        return;
  
      auto subscriptType =
          getTypeOfMember(SD, dynamicLookupInfo)->getAs<AnyFunctionType>();
      if (!subscriptType)
        return;
  
      Optional<NotRecommendedReason> NotRecommended;
      bool implictlyAsync = false;
      analyzeActorIsolation(SD, subscriptType, implictlyAsync, NotRecommended);
  
      if (!isForCaching() && !NotRecommended && implictlyAsync &&
          !CanCurrDeclContextHandleAsync) {
        NotRecommended = NotRecommendedReason::InvalidAsyncContext;
      }
  
      CodeCompletionResultBuilder Builder(
          Sink, CodeCompletionResult::ResultKind::Declaration,
          getSemanticContext(SD, Reason, dynamicLookupInfo), expectedTypeContext);
      Builder.setAssociatedDecl(SD);
  
      if (NotRecommended)
        Builder.setNotRecommended(*NotRecommended);
  
      // '\TyName#^TOKEN^#' requires leading dot.
      if (!HaveDot && IsAfterSwiftKeyPathRoot)
        Builder.addLeadingDot();
  
      if (NeedOptionalUnwrap) {
        Builder.setNumBytesToErase(NumBytesToEraseForOptionalUnwrap);
        Builder.addQuestionMark();
      }
  
      Builder.addLeftBracket();
      addCallArgumentPatterns(Builder, subscriptType, SD->getIndices(),
                              SD->getGenericSignatureOfContext(), true);
      Builder.addRightBracket();
  
      // Add a type annotation.
      Type resultTy = subscriptType->getResult();
      if (IsDynamicLookup) {
        // Values of properties that were found on a AnyObject have
        // Optional<T> type.
        resultTy = OptionalType::get(resultTy);
      }
  
      if (implictlyAsync)
        Builder.addAnnotatedAsync();
  
      addTypeAnnotation(Builder, resultTy, SD->getGenericSignatureOfContext());
    }
  
    void addNominalTypeRef(const NominalTypeDecl *NTD, DeclVisibilityKind Reason,
                           DynamicLookupInfo dynamicLookupInfo) {
      CodeCompletionResultBuilder Builder(
          Sink, CodeCompletionResult::ResultKind::Declaration,
          getSemanticContext(NTD, Reason, dynamicLookupInfo),
          expectedTypeContext);
      Builder.setAssociatedDecl(NTD);
      addLeadingDot(Builder);
      Builder.addBaseName(NTD->getName().str());
  
      addTypeAnnotation(Builder, NTD->getDeclaredType());
  
      // Override the type relation for NominalTypes. Use the better relation
      // for the metatypes and the instance type. For example,
      //
      //   func receiveInstance(_: Int) {}
      //   func receiveMetatype(_: Int.Type) {}
      //
      // We want to suggest 'Int' as 'Identical' for both arguments.
      Builder.setExpectedTypeRelation(std::max(
          calculateMaxTypeRelation(NTD->getDeclaredInterfaceType(),
                                   expectedTypeContext, CurrDeclContext),
          calculateMaxTypeRelation(NTD->getInterfaceType(), expectedTypeContext,
                                   CurrDeclContext)));
    }
  
    void addTypeAliasRef(const TypeAliasDecl *TAD, DeclVisibilityKind Reason,
                         DynamicLookupInfo dynamicLookupInfo) {
      CodeCompletionResultBuilder Builder(
          Sink, CodeCompletionResult::ResultKind::Declaration,
          getSemanticContext(TAD, Reason, dynamicLookupInfo),
          expectedTypeContext);
      Builder.setAssociatedDecl(TAD);
      addLeadingDot(Builder);
      Builder.addBaseName(TAD->getName().str());
      if (auto underlyingType = TAD->getUnderlyingType()) {
        if (underlyingType->hasError()) {
          Type parentType;
          if (auto nominal = TAD->getDeclContext()->getSelfNominalTypeDecl()) {
            parentType = nominal->getDeclaredInterfaceType();
          }
          addTypeAnnotation(
                        Builder,
                        TypeAliasType::get(const_cast<TypeAliasDecl *>(TAD),
                                           parentType, SubstitutionMap(),
                                           underlyingType));
  
        } else {
          addTypeAnnotation(Builder, underlyingType);
        }
      }
    }
  
    void addGenericTypeParamRef(const GenericTypeParamDecl *GP,
                                DeclVisibilityKind Reason,
                                DynamicLookupInfo dynamicLookupInfo) {
      CodeCompletionResultBuilder Builder(
          Sink, CodeCompletionResult::ResultKind::Declaration,
          getSemanticContext(GP, Reason, dynamicLookupInfo), expectedTypeContext);
      Builder.setAssociatedDecl(GP);
      addLeadingDot(Builder);
      Builder.addBaseName(GP->getName().str());
      addTypeAnnotation(Builder, GP->getDeclaredInterfaceType());
    }
  
    void addAssociatedTypeRef(const AssociatedTypeDecl *AT,
                              DeclVisibilityKind Reason,
                              DynamicLookupInfo dynamicLookupInfo) {
      CodeCompletionResultBuilder Builder(
          Sink, CodeCompletionResult::ResultKind::Declaration,
          getSemanticContext(AT, Reason, dynamicLookupInfo), expectedTypeContext);
      Builder.setAssociatedDecl(AT);
      addLeadingDot(Builder);
      Builder.addBaseName(AT->getName().str());
      if (Type T = getAssociatedTypeType(AT))
        addTypeAnnotation(Builder, T);
    }
  
    void addPrecedenceGroupRef(PrecedenceGroupDecl *PGD) {
      auto semanticContext =
          getSemanticContext(PGD, DeclVisibilityKind::VisibleAtTopLevel, {});
      CodeCompletionResultBuilder builder(
        Sink, CodeCompletionResult::ResultKind::Declaration,
        semanticContext, {});
  
      builder.addBaseName(PGD->getName().str());
      builder.setAssociatedDecl(PGD);
    };
  
    void addEnumElementRef(const EnumElementDecl *EED, DeclVisibilityKind Reason,
                           DynamicLookupInfo dynamicLookupInfo,
                           bool HasTypeContext) {
      if (!EED->hasName() ||
          !EED->isAccessibleFrom(CurrDeclContext) ||
          EED->shouldHideFromEditor())
        return;
  
      CodeCompletionResultBuilder Builder(
          Sink, CodeCompletionResult::ResultKind::Declaration,
          getSemanticContext(EED, Reason, dynamicLookupInfo),
          expectedTypeContext);
      Builder.setAssociatedDecl(EED);
  
      addLeadingDot(Builder);
      addValueBaseName(Builder, EED->getBaseIdentifier());
  
      // Enum element is of function type; (Self.type) -> Self or
      // (Self.Type) -> (Args...) -> Self.
      Type EnumType = getTypeOfMember(EED, dynamicLookupInfo);
      if (EnumType->is<AnyFunctionType>())
        EnumType = EnumType->castTo<AnyFunctionType>()->getResult();
  
      if (EnumType->is<FunctionType>()) {
        Builder.addLeftParen();
        addCallArgumentPatterns(Builder, EnumType->castTo<FunctionType>(),
                                EED->getParameterList(),
                                EED->getGenericSignatureOfContext());
        Builder.addRightParen();
  
        // Extract result as the enum type.
        EnumType = EnumType->castTo<FunctionType>()->getResult();
      }
  
      addTypeAnnotation(Builder, EnumType, EED->getGenericSignatureOfContext());
  
      if (isUnresolvedMemberIdealType(EnumType))
        Builder.addFlair(CodeCompletionFlairBit::ExpressionSpecific);
    }
  
    void addKeyword(StringRef Name, Type TypeAnnotation = Type(),
                    SemanticContextKind SK = SemanticContextKind::None,
                    CodeCompletionKeywordKind KeyKind
                      = CodeCompletionKeywordKind::None,
                    unsigned NumBytesToErase = 0) {
      CodeCompletionResultBuilder Builder(
          Sink, CodeCompletionResult::ResultKind::Keyword, SK,
          expectedTypeContext);
      addLeadingDot(Builder);
      Builder.addKeyword(Name);
      Builder.setKeywordKind(KeyKind);
      if (TypeAnnotation)
        addTypeAnnotation(Builder, TypeAnnotation);
      if (NumBytesToErase > 0)
        Builder.setNumBytesToErase(NumBytesToErase);
    }
  
    void addKeyword(StringRef Name, StringRef TypeAnnotation,
                    CodeCompletionKeywordKind KeyKind
                      = CodeCompletionKeywordKind::None,
                    CodeCompletionFlair flair = {}) {
      CodeCompletionResultBuilder Builder(
          Sink,
          CodeCompletionResult::ResultKind::Keyword,
          SemanticContextKind::None, expectedTypeContext);
      Builder.addFlair(flair);
      addLeadingDot(Builder);
      Builder.addKeyword(Name);
      Builder.setKeywordKind(KeyKind);
      if (!TypeAnnotation.empty())
        Builder.addTypeAnnotation(TypeAnnotation);
    }
  
    void addDeclAttrParamKeyword(StringRef Name, StringRef Annotation,
                               bool NeedSpecify) {
      CodeCompletionResultBuilder Builder(
          Sink,
          CodeCompletionResult::ResultKind::Keyword,
          SemanticContextKind::None, expectedTypeContext);
      Builder.addDeclAttrParamKeyword(Name, Annotation, NeedSpecify);
    }
  
    void addDeclAttrKeyword(StringRef Name, StringRef Annotation) {
      CodeCompletionResultBuilder Builder(
          Sink,
          CodeCompletionResult::ResultKind::Keyword,
          SemanticContextKind::None, expectedTypeContext);
      Builder.addDeclAttrKeyword(Name, Annotation);
    }
  
    /// Add the compound function name for the given function.
    /// Returns \c true if the compound function name is actually used.
    bool addCompoundFunctionNameIfDesiable(AbstractFunctionDecl *AFD,
                                           DeclVisibilityKind Reason,
                                           DynamicLookupInfo dynamicLookupInfo) {
      auto funcTy =
          getTypeOfMember(AFD, dynamicLookupInfo)->getAs<AnyFunctionType>();
      bool dropCurryLevel = funcTy && AFD->getDeclContext()->isTypeContext() &&
          !isImplicitlyCurriedInstanceMethod(AFD);
      if (dropCurryLevel)
        funcTy = funcTy->getResult()->getAs<AnyFunctionType>();
  
      bool useFunctionReference = PreferFunctionReferencesToCalls;
      if (!useFunctionReference && funcTy) {
        auto maxRel = calculateMaxTypeRelation(funcTy, expectedTypeContext,
                                               CurrDeclContext);
        useFunctionReference =
            maxRel >= CodeCompletionResult::ExpectedTypeRelation::Convertible;
      }
      if (!useFunctionReference)
        return false;
  
      // Check for duplicates with the adjusted type too.
      if (dropCurryLevel && isDuplicate(AFD, funcTy))
        return true;
  
      CodeCompletionResultBuilder Builder(
          Sink, CodeCompletionResult::ResultKind::Declaration,
          getSemanticContext(AFD, Reason, dynamicLookupInfo),
          expectedTypeContext);
      Builder.setAssociatedDecl(AFD);
  
      // Base name
      addLeadingDot(Builder);
      addValueBaseName(Builder, AFD->getBaseName());
  
      // Add the argument labels.
      const auto ArgLabels = AFD->getName().getArgumentNames();
      if (!ArgLabels.empty()) {
        if (!HaveLParen)
          Builder.addLeftParen();
        else
          Builder.addAnnotatedLeftParen();
  
        for (auto ArgLabel : ArgLabels) {
          if (ArgLabel.empty())
            Builder.addTextChunk("_");
          else
            Builder.addTextChunk(ArgLabel.str());
          Builder.addTextChunk(":");
        }
  
        Builder.addRightParen();
      }
  
      if (funcTy)
        addTypeAnnotation(Builder, funcTy, AFD->getGenericSignatureOfContext());
  
      return true;
    }
  
  private:
  
    /// Returns true if duplicate checking is enabled (via
    /// \c shouldCheckForDuplicates) and this decl + type combination has been
    /// checked previously. Returns false otherwise.
    bool isDuplicate(const ValueDecl *D, Type Ty) {
      if (!CheckForDuplicates)
        return false;
      return !PreviouslySeen.insert({D, Ty}).second;
    }
  
    /// Returns true if duplicate checking is enabled (via
    /// \c shouldCheckForDuplicates) and this decl has been checked previously
    /// with the type according to \c getTypeOfMember. Returns false otherwise.
    bool isDuplicate(const ValueDecl *D, DynamicLookupInfo dynamicLookupInfo) {
      if (!CheckForDuplicates)
        return false;
      Type Ty = getTypeOfMember(D, dynamicLookupInfo);
      return !PreviouslySeen.insert({D, Ty}).second;
    }
  
  public:
  
    // Implement swift::VisibleDeclConsumer.
    void foundDecl(ValueDecl *D, DeclVisibilityKind Reason,
                   DynamicLookupInfo dynamicLookupInfo) override {
      assert(Reason !=
               DeclVisibilityKind::MemberOfProtocolDerivedByCurrentNominal &&
             "Including derived requirement in non-override lookup");
  
      if (D->shouldHideFromEditor())
        return;
  
      if (IsKeyPathExpr && !KeyPathFilter(D, Reason))
        return;
  
      if (IsSwiftKeyPathExpr && !SwiftKeyPathFilter(D, Reason))
        return;
  
      // If we've seen this decl+type before (possible when multiple lookups are
      // performed e.g. because of ambiguous base types), bail.
      if (isDuplicate(D, dynamicLookupInfo))
        return;
      
      // FIXME(InterfaceTypeRequest): Remove this.
      (void)D->getInterfaceType();
      switch (Kind) {
      case LookupKind::ValueExpr:
        if (auto *CD = dyn_cast<ConstructorDecl>(D)) {
          // Do we want compound function names here?
          if (addCompoundFunctionNameIfDesiable(CD, Reason, dynamicLookupInfo))
            return;
  
          if (auto MT = ExprType->getAs<AnyMetatypeType>()) {
            Type Ty = MT->getInstanceType();
            assert(Ty && "Cannot find instance type.");
  
            // If instance type is type alias, show users that the constructed
            // type is the typealias instead of the underlying type of the alias.
            Optional<Type> Result = None;
            if (!CD->getInterfaceType()->is<ErrorType>() &&
                isa<TypeAliasType>(Ty.getPointer()) &&
                Ty->getDesugaredType() ==
                  CD->getResultInterfaceType().getPointer()) {
              Result = Ty;
            }
            // If the expression type is not a static metatype or an archetype, the base
            // is not a type. Direct call syntax is illegal on values, so we only add
            // initializer completions if we do not have a left parenthesis and either
            // the initializer is required, the base type's instance type is not a class,
            // or this is a 'self' or 'super' reference.
            if (IsStaticMetatype || IsUnresolvedMember || Ty->is<ArchetypeType>())
              addConstructorCall(CD, Reason, dynamicLookupInfo, None, Result,
                                 /*isOnType*/ true);
            else if ((IsSelfRefExpr || IsSuperRefExpr || !Ty->is<ClassType>() ||
                      CD->isRequired()) && !HaveLParen)
              addConstructorCall(CD, Reason, dynamicLookupInfo, None, Result,
                                 /*isOnType*/ false);
            return;
          }
          if (!HaveLParen) {
            auto CDC = dyn_cast<ConstructorDecl>(CurrDeclContext);
            if (!CDC)
              return;
  
            // For classes, we do not want 'init' completions for 'self' in
            // non-convenience initializers and for 'super' in convenience initializers.
            if (ExprType->is<ClassType>()) {
              if ((IsSelfRefExpr && !CDC->isConvenienceInit()) ||
                  (IsSuperRefExpr && CDC->isConvenienceInit()))
                return;
            }
            if (IsSelfRefExpr || IsSuperRefExpr)
              addConstructorCall(CD, Reason, dynamicLookupInfo, None, None,
                                 /*IsOnType=*/false);
          }
          return;
        }
  
        if (HaveLParen)
          return;
  
        LLVM_FALLTHROUGH;
  
      case LookupKind::ValueInDeclContext:
      case LookupKind::ImportFromModule:
        if (auto *VD = dyn_cast<VarDecl>(D)) {
          addVarDeclRef(VD, Reason, dynamicLookupInfo);
          return;
        }
  
        if (auto *FD = dyn_cast<FuncDecl>(D)) {
          // We cannot call operators with a postfix parenthesis syntax.
          if (FD->isBinaryOperator() || FD->isUnaryOperator())
            return;
  
          // We cannot call accessors.  We use VarDecls and SubscriptDecls to
          // produce completions that refer to getters and setters.
          if (isa<AccessorDecl>(FD))
            return;
  
          // Do we want compound function names here?
          if (addCompoundFunctionNameIfDesiable(FD, Reason, dynamicLookupInfo))
            return;
  
          addMethodCall(FD, Reason, dynamicLookupInfo);
  
          // SE-0253: Callable values of user-defined nominal types.
          if (FD->isCallAsFunctionMethod() && !HaveDot &&
              (!ExprType || !ExprType->is<AnyMetatypeType>())) {
            Type funcType = getTypeOfMember(FD, dynamicLookupInfo)
                                ->castTo<AnyFunctionType>()
                                ->getResult();
  
            // Check for duplicates with the adjusted type too.
            if (isDuplicate(FD, funcType))
              return;
  
            addFunctionCallPattern(
                funcType->castTo<AnyFunctionType>(), FD,
                getSemanticContext(FD, Reason, dynamicLookupInfo));
          }
          return;
        }
  
        if (auto *NTD = dyn_cast<NominalTypeDecl>(D)) {
          addNominalTypeRef(NTD, Reason, dynamicLookupInfo);
          addConstructorCallsForType(NTD->getDeclaredInterfaceType(),
                                     NTD->getName(), Reason, dynamicLookupInfo);
          return;
        }
  
        if (auto *TAD = dyn_cast<TypeAliasDecl>(D)) {
          addTypeAliasRef(TAD, Reason, dynamicLookupInfo);
          auto type = TAD->mapTypeIntoContext(TAD->getDeclaredInterfaceType());
          if (type->mayHaveMembers())
            addConstructorCallsForType(type, TAD->getName(), Reason,
                                       dynamicLookupInfo);
          return;
        }
  
        if (auto *GP = dyn_cast<GenericTypeParamDecl>(D)) {
          addGenericTypeParamRef(GP, Reason, dynamicLookupInfo);
          for (auto *protocol : GP->getConformingProtocols())
            addConstructorCallsForType(protocol->getDeclaredInterfaceType(),
                                       GP->getName(), Reason, dynamicLookupInfo);
          return;
        }
  
        if (auto *AT = dyn_cast<AssociatedTypeDecl>(D)) {
          addAssociatedTypeRef(AT, Reason, dynamicLookupInfo);
          return;
        }
  
        if (auto *EED = dyn_cast<EnumElementDecl>(D)) {
          addEnumElementRef(EED, Reason, dynamicLookupInfo,
                            /*HasTypeContext=*/false);
          return;
        }
  
        // Swift key path allows .[0]
        if (auto *SD = dyn_cast<SubscriptDecl>(D)) {
          addSubscriptCall(SD, Reason, dynamicLookupInfo);
          return;
        }
        return;
  
      case LookupKind::EnumElement:
        handleEnumElement(D, Reason, dynamicLookupInfo);
        return;
  
      case LookupKind::Type:
      case LookupKind::TypeInDeclContext:
        if (auto *NTD = dyn_cast<NominalTypeDecl>(D)) {
          addNominalTypeRef(NTD, Reason, dynamicLookupInfo);
          return;
        }
  
        if (auto *GP = dyn_cast<GenericTypeParamDecl>(D)) {
          addGenericTypeParamRef(GP, Reason, dynamicLookupInfo);
          return;
        }
  
        LLVM_FALLTHROUGH;
      case LookupKind::GenericRequirement:
  
        if (TypeAliasDecl *TAD = dyn_cast<TypeAliasDecl>(D)) {
          if (Kind == LookupKind::GenericRequirement &&
              !canBeUsedAsRequirementFirstType(BaseType, TAD))
            return;
          addTypeAliasRef(TAD, Reason, dynamicLookupInfo);
          return;
        }
  
        if (auto *AT = dyn_cast<AssociatedTypeDecl>(D)) {
          addAssociatedTypeRef(AT, Reason, dynamicLookupInfo);
          return;
        }
  
        return;
      }
    }
  
    bool handleEnumElement(ValueDecl *D, DeclVisibilityKind Reason,
                           DynamicLookupInfo dynamicLookupInfo) {
      if (auto *EED = dyn_cast<EnumElementDecl>(D)) {
        addEnumElementRef(EED, Reason, dynamicLookupInfo,
                          /*HasTypeContext=*/true);
        return true;
      } else if (auto *ED = dyn_cast<EnumDecl>(D)) {
        llvm::DenseSet<EnumElementDecl *> Elements;
        ED->getAllElements(Elements);
        for (auto *Ele : Elements) {
          addEnumElementRef(Ele, Reason, dynamicLookupInfo,
                            /*HasTypeContext=*/true);
        }
        return true;
      }
      return false;
    }
  
    bool tryTupleExprCompletions(Type ExprType) {
      auto *TT = ExprType->getAs<TupleType>();
      if (!TT)
        return false;
  
      unsigned Index = 0;
      for (auto TupleElt : TT->getElements()) {
        CodeCompletionResultBuilder Builder(
            Sink,
            CodeCompletionResult::ResultKind::Pattern,
            SemanticContextKind::CurrentNominal, expectedTypeContext);
        addLeadingDot(Builder);
        if (TupleElt.hasName()) {
          Builder.addBaseName(TupleElt.getName().str());
        } else {
          llvm::SmallString<4> IndexStr;
          {
            llvm::raw_svector_ostream OS(IndexStr);
            OS << Index;
          }
          Builder.addBaseName(IndexStr.str());
        }
        addTypeAnnotation(Builder, TupleElt.getType());
        ++Index;
      }
      return true;
    }
  
    bool tryFunctionCallCompletions(Type ExprType, const ValueDecl *VD, Optional<SemanticContextKind> SemanticContext = None) {
      ExprType = ExprType->getRValueType();
      if (auto AFT = ExprType->getAs<AnyFunctionType>()) {
        if (auto *AFD = dyn_cast_or_null<AbstractFunctionDecl>(VD)) {
          addFunctionCallPattern(AFT, AFD, SemanticContext);
        } else {
          addFunctionCallPattern(AFT);
        }
        return true;
      }
      return false;
    }
  
    bool tryModuleCompletions(Type ExprType, bool TypesOnly = false) {
      if (auto MT = ExprType->getAs<ModuleType>()) {
        ModuleDecl *M = MT->getModule();
  
        // Only lookup this module's symbols from the cache if it is not the
        // current module.
        if (M == CurrModule)
          return false;
  
        // If the module is shadowed by a separately imported overlay(s), look up
        // the symbols from the overlay(s) instead.
        SmallVector<ModuleDecl *, 1> ShadowingOrOriginal;
        if (auto *SF = CurrDeclContext->getParentSourceFile()) {
          SF->getSeparatelyImportedOverlays(M, ShadowingOrOriginal);
          if (ShadowingOrOriginal.empty())
            ShadowingOrOriginal.push_back(M);
        }
        for (ModuleDecl *M: ShadowingOrOriginal) {
          RequestedResultsTy Request = RequestedResultsTy::fromModule(M)
              .needLeadingDot(needDot())
              .withModuleQualifier(false);
          if (TypesOnly)
            Request = Request.onlyTypes();
          RequestedCachedResults.push_back(Request);
        }
        return true;
      }
      return false;
    }
  
    /// If the given ExprType is optional, this adds completions for the unwrapped
    /// type.
    ///
    /// \return true if the given type was Optional .
    bool tryUnwrappedCompletions(Type ExprType, bool isIUO) {
      // FIXME: consider types convertible to T?.
  
      ExprType = ExprType->getRValueType();
      // FIXME: We don't always pass down whether a type is from an
      // unforced IUO.
      if (isIUO) {
        if (Type Unwrapped = ExprType->getOptionalObjectType()) {
          lookupVisibleMemberDecls(*this, Unwrapped, CurrDeclContext,
                                   IncludeInstanceMembers,
                                   /*includeDerivedRequirements*/false,
                                   /*includeProtocolExtensionMembers*/true);
          return true;
        }
        assert(IsUnwrappedOptional && "IUOs should be optional if not bound/forced");
        return false;
      }
  
      if (Type Unwrapped = ExprType->getOptionalObjectType()) {
        llvm::SaveAndRestore<bool> ChangeNeedOptionalUnwrap(NeedOptionalUnwrap,
                                                            true);
        if (DotLoc.isValid()) {
          // Let's not erase the dot if the completion is after a swift key path
          // root because \A?.?.member is the correct way to access wrapped type
          // member from an optional key path root.
          auto loc = IsAfterSwiftKeyPathRoot ? DotLoc.getAdvancedLoc(1) : DotLoc;
          NumBytesToEraseForOptionalUnwrap = Ctx.SourceMgr.getByteDistance(
              loc, Ctx.SourceMgr.getCodeCompletionLoc());
        } else {
          NumBytesToEraseForOptionalUnwrap = 0;
        }
        if (NumBytesToEraseForOptionalUnwrap <=
            CodeCompletionResult::MaxNumBytesToErase) {
          if (!tryTupleExprCompletions(Unwrapped)) {
            lookupVisibleMemberDecls(*this, Unwrapped, CurrDeclContext,
                                     IncludeInstanceMembers,
                                     /*includeDerivedRequirements*/false,
                                     /*includeProtocolExtensionMembers*/true);
          }
        }
        return true;
      }
      return false;
    }
  
    void getPostfixKeywordCompletions(Type ExprType, Expr *ParsedExpr) {
      if (IsSuperRefExpr)
        return;
  
      if (!ExprType->getAs<ModuleType>()) {
        addKeyword(getTokenText(tok::kw_self), ExprType->getRValueType(),
                   SemanticContextKind::CurrentNominal,
                   CodeCompletionKeywordKind::kw_self);
      }
  
      if (isa<TypeExpr>(ParsedExpr)) {
        if (auto *T = ExprType->getAs<AnyMetatypeType>()) {
          auto instanceTy = T->getInstanceType();
          if (instanceTy->isAnyExistentialType()) {
            addKeyword("Protocol", MetatypeType::get(instanceTy),
                       SemanticContextKind::CurrentNominal);
            addKeyword("Type", ExistentialMetatypeType::get(instanceTy),
                       SemanticContextKind::CurrentNominal);
          } else {
            addKeyword("Type", MetatypeType::get(instanceTy),
                       SemanticContextKind::CurrentNominal);
          }
        }
      }
    }
  
    void getValueExprCompletions(Type ExprType, ValueDecl *VD = nullptr) {
      Kind = LookupKind::ValueExpr;
      NeedLeadingDot = !HaveDot;
  
      ExprType = ExprType->getRValueType();
      assert(!ExprType->hasTypeParameter());
  
      this->ExprType = ExprType;
  
      // Open existential types, so that lookupVisibleMemberDecls() can properly
      // substitute them.
      bool WasOptional = false;
      if (auto OptionalType = ExprType->getOptionalObjectType()) {
        ExprType = OptionalType;
        WasOptional = true;
      }
  
      if (!ExprType->getMetatypeInstanceType()->isAnyObject())
        if (ExprType->isAnyExistentialType())
          ExprType = OpenedArchetypeType::getAny(ExprType);
  
      if (!IsSelfRefExpr && !IsSuperRefExpr && ExprType->getAnyNominal() &&
          ExprType->getAnyNominal()->isActor()) {
        IsCrossActorReference = true;
      }
  
      if (WasOptional)
        ExprType = OptionalType::get(ExprType);
  
      // Handle special cases
      bool isIUO = VD && VD->isImplicitlyUnwrappedOptional();
      if (tryFunctionCallCompletions(ExprType, VD))
        return;
      if (tryModuleCompletions(ExprType))
        return;
      if (tryTupleExprCompletions(ExprType))
        return;
      // Don't check/return so we still add the members of Optional itself below
      tryUnwrappedCompletions(ExprType, isIUO);
  
      lookupVisibleMemberDecls(*this, ExprType, CurrDeclContext,
                               IncludeInstanceMembers,
                               /*includeDerivedRequirements*/false,
                               /*includeProtocolExtensionMembers*/true);
    }
  
    void collectOperators(SmallVectorImpl<OperatorDecl *> &results) {
      assert(CurrDeclContext);
      for (auto import : namelookup::getAllImports(CurrDeclContext))
        import.importedModule->getOperatorDecls(results);
    }
  
    void addPostfixBang(Type resultType) {
      CodeCompletionResultBuilder builder(
          Sink, CodeCompletionResult::ResultKind::BuiltinOperator,
          SemanticContextKind::None, {});
      // FIXME: we can't use the exclamation mark chunk kind, or it isn't
      // included in the completion name.
      builder.addTextChunk("!");
      assert(resultType);
      addTypeAnnotation(builder, resultType);
    }
  
    void addPostfixOperatorCompletion(OperatorDecl *op, Type resultType) {
      // FIXME: we should get the semantic context of the function, not the
      // operator decl.
      auto semanticContext =
          getSemanticContext(op, DeclVisibilityKind::VisibleAtTopLevel, {});
      CodeCompletionResultBuilder builder(
          Sink, CodeCompletionResult::ResultKind::Declaration, semanticContext,
          {});
  
      // FIXME: handle variable amounts of space.
      if (HaveLeadingSpace)
        builder.setNumBytesToErase(1);
      builder.setAssociatedDecl(op);
      builder.addBaseName(op->getName().str());
      assert(resultType);
      addTypeAnnotation(builder, resultType);
    }
  
    void tryPostfixOperator(Expr *expr, PostfixOperatorDecl *op) {
      ConcreteDeclRef referencedDecl;
      FunctionType *funcTy = getTypeOfCompletionOperator(
          const_cast<DeclContext *>(CurrDeclContext), expr, op->getName(),
          DeclRefKind::PostfixOperator, referencedDecl);
      if (!funcTy)
        return;
  
      // TODO: Use referencedDecl (FuncDecl) instead of 'op' (OperatorDecl).
      addPostfixOperatorCompletion(op, funcTy->getResult());
    }
  
    void addAssignmentOperator(Type RHSType, Type resultType) {
      CodeCompletionResultBuilder builder(
          Sink, CodeCompletionResult::ResultKind::BuiltinOperator,
          SemanticContextKind::None, {});
  
      if (HaveLeadingSpace)
        builder.addAnnotatedWhitespace(" ");
      else
        builder.addWhitespace(" ");
      builder.addEqual();
      builder.addWhitespace(" ");
      assert(RHSType && resultType);
      Type contextTy;
      if (auto typeContext = CurrDeclContext->getInnermostTypeContext())
        contextTy = typeContext->getDeclaredTypeInContext();
      builder.addCallArgument(Identifier(), RHSType, contextTy);
      addTypeAnnotation(builder, resultType);
    }
  
    void addInfixOperatorCompletion(OperatorDecl *op, Type resultType,
                                    Type RHSType) {
      // FIXME: we should get the semantic context of the function, not the
      // operator decl.
      auto semanticContext =
          getSemanticContext(op, DeclVisibilityKind::VisibleAtTopLevel, {});
      CodeCompletionResultBuilder builder(
          Sink, CodeCompletionResult::ResultKind::Declaration, semanticContext,
          {});
      builder.setAssociatedDecl(op);
  
      if (HaveLeadingSpace)
        builder.addAnnotatedWhitespace(" ");
      else
        builder.addWhitespace(" ");
      builder.addBaseName(op->getName().str());
      builder.addWhitespace(" ");
      if (RHSType) {
        Type contextTy;
        if (auto typeContext = CurrDeclContext->getInnermostTypeContext())
          contextTy = typeContext->getDeclaredTypeInContext();
        builder.addCallArgument(Identifier(), RHSType, contextTy);
      }
      if (resultType)
        addTypeAnnotation(builder, resultType);
    }
  
    void tryInfixOperatorCompletion(Expr *foldedExpr, InfixOperatorDecl *op) {
      ConcreteDeclRef referencedDecl;
      FunctionType *funcTy = getTypeOfCompletionOperator(
          const_cast<DeclContext *>(CurrDeclContext), foldedExpr, op->getName(),
          DeclRefKind::BinaryOperator, referencedDecl);
      if (!funcTy)
        return;
  
      Type lhsTy = funcTy->getParams()[0].getPlainType();
      Type rhsTy = funcTy->getParams()[1].getPlainType();
      Type resultTy = funcTy->getResult();
  
      // Don't complete optional operators on non-optional types.
      if (!lhsTy->getRValueType()->getOptionalObjectType()) {
        // 'T ?? T'
        if (op->getName().str() == "??")
          return;
        // 'T == nil'
        if (auto NT = rhsTy->getNominalOrBoundGenericNominal())
          if (NT->getName() ==
              CurrDeclContext->getASTContext().Id_OptionalNilComparisonType)
            return;
      }
  
      // If the right-hand side and result type are both type parameters, we're
      // not providing a useful completion.
      if (resultTy->isTypeParameter() && rhsTy->isTypeParameter())
        return;
  
      // TODO: Use referencedDecl (FuncDecl) instead of 'op' (OperatorDecl).
      addInfixOperatorCompletion(op, funcTy->getResult(),
                                 funcTy->getParams()[1].getPlainType());
    }
  
    Expr *typeCheckLeadingSequence(Expr *LHS, ArrayRef<Expr *> leadingSequence) {
      if (leadingSequence.empty())
        return LHS;
  
      SourceRange sequenceRange(leadingSequence.front()->getStartLoc(),
                                LHS->getEndLoc());
      auto *expr = findParsedExpr(CurrDeclContext, sequenceRange);
      if (!expr)
        return LHS;
  
      if (expr->getType() && !expr->getType()->hasError())
        return expr;
  
      if (!typeCheckExpression(const_cast<DeclContext *>(CurrDeclContext), expr))
        return expr;
      return LHS;
    }
  
    void getOperatorCompletions(Expr *LHS, ArrayRef<Expr *> leadingSequence) {
      if (IsSuperRefExpr)
        return;
  
      Expr *foldedExpr = typeCheckLeadingSequence(LHS, leadingSequence);
  
      SmallVector<OperatorDecl *, 16> operators;
      collectOperators(operators);
      // FIXME: this always chooses the first operator with the given name.
      llvm::DenseSet<Identifier> seenPostfixOperators;
      llvm::DenseSet<Identifier> seenInfixOperators;
  
      for (auto op : operators) {
        switch (op->getKind()) {
        case DeclKind::PrefixOperator:
          // Don't insert prefix operators in postfix position.
          // FIXME: where should these get completed?
          break;
        case DeclKind::PostfixOperator:
          if (seenPostfixOperators.insert(op->getName()).second)
            tryPostfixOperator(LHS, cast<PostfixOperatorDecl>(op));
          break;
        case DeclKind::InfixOperator:
          if (seenInfixOperators.insert(op->getName()).second)
            tryInfixOperatorCompletion(foldedExpr, cast<InfixOperatorDecl>(op));
          break;
        default:
          llvm_unreachable("unexpected operator kind");
        }
      }
  
      if (leadingSequence.empty() && LHS->getType() &&
          LHS->getType()->hasLValueType()) {
        addAssignmentOperator(LHS->getType()->getRValueType(),
                              CurrDeclContext->getASTContext().TheEmptyTupleType);
      }
  
      // FIXME: unify this with the ?.member completions.
      if (auto T = LHS->getType())
        if (auto ValueT = T->getRValueType()->getOptionalObjectType())
          addPostfixBang(ValueT);
    }
  
    void addTypeRelationFromProtocol(CodeCompletionResultBuilder &builder,
                                     CodeCompletionLiteralKind kind) {
      // Check for matching ExpectedTypes.
      auto *P = Ctx.getProtocol(protocolForLiteralKind(kind));
      for (auto T : expectedTypeContext.possibleTypes) {
        if (!T)
          continue;
  
        auto typeRelation = CodeCompletionResult::Identical;
        // Convert through optional types unless we're looking for a protocol
        // that Optional itself conforms to.
        if (kind != CodeCompletionLiteralKind::NilLiteral) {
          if (auto optionalObjT = T->getOptionalObjectType()) {
            T = optionalObjT;
            typeRelation = CodeCompletionResult::Convertible;
          }
        }
  
        // Check for conformance to the literal protocol.
        if (auto *NTD = T->getAnyNominal()) {
          SmallVector<ProtocolConformance *, 2> conformances;
          if (NTD->lookupConformance(P, conformances)) {
            addTypeAnnotation(builder, T);
            builder.setExpectedTypeRelation(typeRelation);
            return;
          }
        }
      }
  
      // Fallback to showing the default type.
      if (auto defaultTy = defaultTypeLiteralKind(kind, Ctx)) {
        builder.addTypeAnnotation(defaultTy, PrintOptions());
        builder.setExpectedTypeRelation(
            expectedTypeContext.possibleTypes.empty()
                ? CodeCompletionResult::ExpectedTypeRelation::Unknown
                : CodeCompletionResult::ExpectedTypeRelation::Unrelated);
      }
    }
  
    /// Add '#file', '#line', et at.
    void addPoundLiteralCompletions(bool needPound) {
      CodeCompletionFlair flair;
      if (isCodeCompletionAtTopLevelOfLibraryFile(CurrDeclContext))
        flair |= CodeCompletionFlairBit::ExpressionAtNonScriptOrMainFileScope;
  
      auto addFromProto = [&](MagicIdentifierLiteralExpr::Kind magicKind,
                              Optional<CodeCompletionLiteralKind> literalKind) {
        CodeCompletionKeywordKind kwKind;
        switch (magicKind) {
        case MagicIdentifierLiteralExpr::FileIDSpelledAsFile:
          kwKind = CodeCompletionKeywordKind::pound_file;
          break;
        case MagicIdentifierLiteralExpr::FilePathSpelledAsFile:
          // Already handled by above case.
          return;
  #define MAGIC_IDENTIFIER_TOKEN(NAME, TOKEN) \
        case MagicIdentifierLiteralExpr::NAME: \
          kwKind = CodeCompletionKeywordKind::TOKEN; \
          break;
  #define MAGIC_IDENTIFIER_DEPRECATED_TOKEN(NAME, TOKEN)
  #include "swift/AST/MagicIdentifierKinds.def"
        }
  
        StringRef name = MagicIdentifierLiteralExpr::getKindString(magicKind);
        if (!needPound)
          name = name.substr(1);
  
        if (!literalKind) {
          // Pointer type
          addKeyword(name, "UnsafeRawPointer", kwKind, flair);
          return;
        }
  
        CodeCompletionResultBuilder builder(
            Sink, CodeCompletionResult::ResultKind::Keyword,
            SemanticContextKind::None, {});
        builder.addFlair(flair);
        builder.setLiteralKind(literalKind.getValue());
        builder.setKeywordKind(kwKind);
        builder.addBaseName(name);
        addTypeRelationFromProtocol(builder, literalKind.getValue());
      };
  
  #define MAGIC_STRING_IDENTIFIER(NAME, STRING, SYNTAX_KIND) \
      addFromProto(MagicIdentifierLiteralExpr::NAME, \
                   CodeCompletionLiteralKind::StringLiteral);
  #define MAGIC_INT_IDENTIFIER(NAME, STRING, SYNTAX_KIND) \
      addFromProto(MagicIdentifierLiteralExpr::NAME, \
                   CodeCompletionLiteralKind::IntegerLiteral);
  #define MAGIC_POINTER_IDENTIFIER(NAME, STRING, SYNTAX_KIND) \
      addFromProto(MagicIdentifierLiteralExpr::NAME, \
                   None);
  #include "swift/AST/MagicIdentifierKinds.def"
    }
  
    void addValueLiteralCompletions() {
      auto &context = CurrDeclContext->getASTContext();
  
      CodeCompletionFlair flair;
      if (isCodeCompletionAtTopLevelOfLibraryFile(CurrDeclContext))
        flair |= CodeCompletionFlairBit::ExpressionAtNonScriptOrMainFileScope;
  
      auto addFromProto = [&](
          CodeCompletionLiteralKind kind,
          llvm::function_ref<void(CodeCompletionResultBuilder &)> consumer,
          bool isKeyword = false) {
  
        CodeCompletionResultBuilder builder(Sink, CodeCompletionResult::Literal,
                                            SemanticContextKind::None, {});
        builder.setLiteralKind(kind);
        builder.addFlair(flair);
  
        consumer(builder);
        addTypeRelationFromProtocol(builder, kind);
      };
  
      // FIXME: the pedantically correct way is to resolve Swift.*LiteralType.
  
      using LK = CodeCompletionLiteralKind;
      using Builder = CodeCompletionResultBuilder;
  
      // Add literal completions that conform to specific protocols.
      addFromProto(LK::IntegerLiteral, [](Builder &builder) {
        builder.addTextChunk("0");
      });
      addFromProto(LK::BooleanLiteral, [](Builder &builder) {
        builder.addBaseName("true");
      }, /*isKeyword=*/true);
      addFromProto(LK::BooleanLiteral, [](Builder &builder) {
        builder.addBaseName("false");
      }, /*isKeyword=*/true);
      addFromProto(LK::NilLiteral, [](Builder &builder) {
        builder.addBaseName("nil");
      }, /*isKeyword=*/true);
      addFromProto(LK::StringLiteral, [&](Builder &builder) {
        builder.addTextChunk("\"");
        builder.addSimpleNamedParameter("abc");
        builder.addTextChunk("\"");
      });
      addFromProto(LK::ArrayLiteral, [&](Builder &builder) {
        builder.addLeftBracket();
        builder.addSimpleNamedParameter("values");
        builder.addRightBracket();
      });
      addFromProto(LK::DictionaryLiteral, [&](Builder &builder) {
        builder.addLeftBracket();
        builder.addSimpleNamedParameter("key");
        builder.addTextChunk(": ");
        builder.addSimpleNamedParameter("value");
        builder.addRightBracket();
      });
  
      // Optionally add object literals.
      if (Sink.includeObjectLiterals) {
        auto floatType = context.getFloatType();
        addFromProto(LK::ColorLiteral, [&](Builder &builder) {
          builder.addBaseName("#colorLiteral");
          builder.addLeftParen();
          builder.addCallArgument(context.getIdentifier("red"), floatType);
          builder.addComma();
          builder.addCallArgument(context.getIdentifier("green"), floatType);
          builder.addComma();
          builder.addCallArgument(context.getIdentifier("blue"), floatType);
          builder.addComma();
          builder.addCallArgument(context.getIdentifier("alpha"), floatType);
          builder.addRightParen();
        });
  
        auto stringType = context.getStringType();
        addFromProto(LK::ImageLiteral, [&](Builder &builder) {
          builder.addBaseName("#imageLiteral");
          builder.addLeftParen();
          builder.addCallArgument(context.getIdentifier("resourceName"),
                                   stringType);
          builder.addRightParen();
        });
      }
  
      // Add tuple completion (item, item).
      {
        CodeCompletionResultBuilder builder(Sink, CodeCompletionResult::Literal,
                                            SemanticContextKind::None, {});
        builder.setLiteralKind(LK::Tuple);
        builder.addFlair(flair);
  
        builder.addLeftParen();
        builder.addSimpleNamedParameter("values");
        builder.addRightParen();
        for (auto T : expectedTypeContext.possibleTypes) {
          if (T && T->is<TupleType>() && !T->isVoid()) {
            addTypeAnnotation(builder, T);
            builder.setExpectedTypeRelation(CodeCompletionResult::Identical);
            break;
          }
        }
      }
    }
  
    void addObjCPoundKeywordCompletions(bool needPound) {
      if (!Ctx.LangOpts.EnableObjCInterop)
        return;
  
      // If the expected type is ObjectiveC.Selector, add #selector. If
      // it's String, add #keyPath.
      bool addedSelector = false;
      bool addedKeyPath = false;
  
      for (auto T : expectedTypeContext.possibleTypes) {
        T = T->lookThroughAllOptionalTypes();
        if (auto structDecl = T->getStructOrBoundGenericStruct()) {
          if (!addedSelector && structDecl->getName() == Ctx.Id_Selector &&
              structDecl->getParentModule()->getName() == Ctx.Id_ObjectiveC) {
            addPoundSelector(needPound);
            if (addedKeyPath)
              break;
            addedSelector = true;
            continue;
          }
        }
  
        if (!addedKeyPath && T->isString()) {
          addPoundKeyPath(needPound);
          if (addedSelector)
            break;
          addedKeyPath = true;
          continue;
        }
      }
    }
  
    struct FilteredDeclConsumer : public swift::VisibleDeclConsumer {
      swift::VisibleDeclConsumer &Consumer;
      DeclFilter Filter;
      FilteredDeclConsumer(swift::VisibleDeclConsumer &Consumer,
                           DeclFilter Filter) : Consumer(Consumer), Filter(Filter) {}
      void foundDecl(ValueDecl *VD, DeclVisibilityKind Kind,
                     DynamicLookupInfo dynamicLookupInfo) override {
        if (Filter(VD, Kind))
          Consumer.foundDecl(VD, Kind, dynamicLookupInfo);
      }
    };
  
    void getValueCompletionsInDeclContext(SourceLoc Loc,
                                          DeclFilter Filter = DefaultFilter,
                                          bool LiteralCompletions = true,
                                          bool ModuleQualifier = true) {
      ExprType = Type();
      Kind = LookupKind::ValueInDeclContext;
      NeedLeadingDot = false;
  
      AccessFilteringDeclConsumer AccessFilteringConsumer(
          CurrDeclContext, *this);
      FilteredDeclConsumer FilteringConsumer(AccessFilteringConsumer, Filter);
  
      lookupVisibleDecls(FilteringConsumer, CurrDeclContext,
                         /*IncludeTopLevel=*/false, Loc);
      RequestedCachedResults.push_back(RequestedResultsTy::toplevelResults()
                                           .withModuleQualifier(ModuleQualifier));
  
      // Manually add any expected nominal types from imported modules so that
      // they get their expected type relation. Don't include protocols, since
      // they can't be initialized from the type name.
      // FIXME: this does not include types that conform to an expected protocol.
      // FIXME: this creates duplicate results.
      for (auto T : expectedTypeContext.possibleTypes) {
        if (auto NT = T->getAs<NominalType>()) {
          if (auto NTD = NT->getDecl()) {
            if (!isa<ProtocolDecl>(NTD) &&
                NTD->getModuleContext() != CurrModule) {
              addNominalTypeRef(NT->getDecl(),
                                DeclVisibilityKind::VisibleAtTopLevel, {});
            }
          }
        }
      }
  
      if (CompletionContext) {
        // FIXME: this is an awful simplification that says all and only enums can
        // use implicit member syntax (leading dot). Computing the accurate answer
        // using lookup (e.g. getUnresolvedMemberCompletions) is too expensive,
        // and for some clients this approximation is good enough.
        CompletionContext->MayUseImplicitMemberExpr =
            std::any_of(expectedTypeContext.possibleTypes.begin(),
                        expectedTypeContext.possibleTypes.end(),
            [](Type T) {
              if (auto *NTD = T->getAnyNominal())
                return isa<EnumDecl>(NTD);
              return false;
            });
      }
  
      if (LiteralCompletions) {
        addValueLiteralCompletions();
        addPoundLiteralCompletions(/*needPound=*/true);
      }
  
      addObjCPoundKeywordCompletions(/*needPound=*/true);
    }
  
    /// Returns \c true if \p VD is an initializer on the \c Optional or \c
    /// Id_OptionalNilComparisonType type from the Swift stdlib.
    static bool isInitializerOnOptional(Type T, ValueDecl *VD) {
      bool IsOptionalType = false;
      IsOptionalType |= static_cast<bool>(T->getOptionalObjectType());
      if (auto *NTD = T->getAnyNominal()) {
        IsOptionalType |= NTD->getBaseIdentifier() ==
                          VD->getASTContext().Id_OptionalNilComparisonType;
      }
      if (IsOptionalType && VD->getModuleContext()->isStdlibModule() &&
          isa<ConstructorDecl>(VD)) {
        return true;
      } else {
        return false;
      }
    }
  
    void getUnresolvedMemberCompletions(Type T) {
      if (!T->mayHaveMembers())
        return;
  
      if (auto objT = T->getOptionalObjectType()) {
        // Add 'nil' keyword with erasing '.' instruction.
        unsigned bytesToErase = 0;
        auto &SM = CurrDeclContext->getASTContext().SourceMgr;
        if (DotLoc.isValid())
          bytesToErase = SM.getByteDistance(DotLoc, SM.getCodeCompletionLoc());
        addKeyword("nil", T, SemanticContextKind::None,
                   CodeCompletionKeywordKind::kw_nil, bytesToErase);
      }
  
      // We can only say .foo where foo is a static member of the contextual
      // type and has the same type (or if the member is a function, then the
      // same result type) as the contextual type.
      FilteredDeclConsumer consumer(
          *this, [=](ValueDecl *VD, DeclVisibilityKind Reason) {
            // In optional context, ignore '.init(<some>)', 'init(nilLiteral:)',
            return !isInitializerOnOptional(T, VD);
          });
  
      auto baseType = MetatypeType::get(T);
      llvm::SaveAndRestore<LookupKind> SaveLook(Kind, LookupKind::ValueExpr);
      llvm::SaveAndRestore<Type> SaveType(ExprType, baseType);
      llvm::SaveAndRestore<bool> SaveUnresolved(IsUnresolvedMember, true);
      lookupVisibleMemberDecls(consumer, baseType, CurrDeclContext,
                               /*includeInstanceMembers=*/false,
                               /*includeDerivedRequirements*/false,
                               /*includeProtocolExtensionMembers*/true);
    }
  
    /// Complete all enum members declared on \p T.
    void getEnumElementPatternCompletions(Type T) {
      if (!isa_and_nonnull<EnumDecl>(T->getAnyNominal()))
        return;
  
      auto baseType = MetatypeType::get(T);
      llvm::SaveAndRestore<LookupKind> SaveLook(Kind, LookupKind::EnumElement);
      llvm::SaveAndRestore<Type> SaveType(ExprType, baseType);
      llvm::SaveAndRestore<bool> SaveUnresolved(IsUnresolvedMember, true);
      lookupVisibleMemberDecls(*this, baseType, CurrDeclContext,
                               /*includeInstanceMembers=*/false,
                               /*includeDerivedRequirements=*/false,
                               /*includeProtocolExtensionMembers=*/true);
    }
  
    void getUnresolvedMemberCompletions(ArrayRef<Type> Types) {
      NeedLeadingDot = !HaveDot;
  
      SmallPtrSet<CanType, 4> seenTypes;
      for (auto T : Types) {
        if (!T || !seenTypes.insert(T->getCanonicalType()).second)
          continue;
  
        if (auto objT = T->getOptionalObjectType()) {
          // If this is optional type, perform completion for the object type.
          // i.e. 'let _: Enum??? = .enumMember' is legal.
          objT = objT->lookThroughAllOptionalTypes();
          if (seenTypes.insert(objT->getCanonicalType()).second)
            getUnresolvedMemberCompletions(objT);
        }
        getUnresolvedMemberCompletions(T);
      }
    }
  
    void addCallArgumentCompletionResults(
        ArrayRef<PossibleParamInfo> ParamInfos,
        bool isLabeledTrailingClosure = false) {
      Type ContextType;
      if (auto typeContext = CurrDeclContext->getInnermostTypeContext())
        ContextType = typeContext->getDeclaredTypeInContext();
  
      for (auto Info : ParamInfos) {
        const auto *Arg = Info.Param;
        if (!Arg)
          continue;
        CodeCompletionResultBuilder Builder(
            Sink, CodeCompletionResult::ResultKind::Pattern,
            // FIXME: SemanticContextKind::Local is not correct.
            // Use 'None' (and fix prioritization) or introduce a new context.
            SemanticContextKind::Local, {});
        Builder.addCallArgument(Arg->getLabel(), Identifier(),
                                Arg->getPlainType(), ContextType,
                                Arg->isVariadic(), Arg->isInOut(),
                                /*isIUO=*/false, Arg->isAutoClosure(),
                                /*useUnderscoreLabel=*/true,
                                isLabeledTrailingClosure);
        Builder.addFlair(CodeCompletionFlairBit::ArgumentLabels);
        auto Ty = Arg->getPlainType();
        if (Arg->isInOut()) {
          Ty = InOutType::get(Ty);
        } else if (Arg->isAutoClosure()) {
          // 'Ty' may be ErrorType.
          if (auto funcTy = Ty->getAs<FunctionType>())
            Ty = funcTy->getResult();
        }
        addTypeAnnotation(Builder, Ty);
        Builder.setExpectedTypeRelation(
            CodeCompletionResult::ExpectedTypeRelation::NotApplicable);
      }
    }
  
    void getTypeCompletions(Type BaseType) {
      if (tryModuleCompletions(BaseType, /*OnlyTypes=*/true))
        return;
      Kind = LookupKind::Type;
      this->BaseType = BaseType;
      NeedLeadingDot = !HaveDot;
      lookupVisibleMemberDecls(*this, MetatypeType::get(BaseType),
                               CurrDeclContext,
                               IncludeInstanceMembers,
                               /*includeDerivedRequirements*/false,
                               /*includeProtocolExtensionMembers*/false);
      if (BaseType->isAnyExistentialType()) {
        addKeyword("Protocol", MetatypeType::get(BaseType));
        addKeyword("Type", ExistentialMetatypeType::get(BaseType));
      } else if (!BaseType->is<ModuleType>()) {
        addKeyword("Type", MetatypeType::get(BaseType));
      }
    }
  
    void getGenericRequirementCompletions(DeclContext *DC,
                                          SourceLoc CodeCompletionLoc) {
      auto genericSig = DC->getGenericSignatureOfContext();
      if (!genericSig)
        return;
  
      for (auto GPT : genericSig.getGenericParams()) {
        addGenericTypeParamRef(GPT->getDecl(),
                               DeclVisibilityKind::GenericParameter, {});
      }
  
      // For non-protocol nominal type decls, only suggest generic parameters.
      if (auto D = DC->getAsDecl())
        if (isa<NominalTypeDecl>(D) && !isa<ProtocolDecl>(D))
          return;
  
      auto typeContext = DC->getInnermostTypeContext();
      if (!typeContext)
        return;
  
      auto selfTy = typeContext->getSelfTypeInContext();
      Kind = LookupKind::GenericRequirement;
      this->BaseType = selfTy;
      NeedLeadingDot = false;
      lookupVisibleMemberDecls(*this, MetatypeType::get(selfTy),
                               CurrDeclContext, IncludeInstanceMembers,
                               /*includeDerivedRequirements*/false,
                               /*includeProtocolExtensionMembers*/true);
      // We not only allow referencing nested types/typealiases directly, but also
      // qualified by the current type. Thus also suggest current self type so the
      // user can do a memberwise lookup on it.
      if (auto SelfType = typeContext->getSelfNominalTypeDecl()) {
        addNominalTypeRef(SelfType, DeclVisibilityKind::LocalVariable,
                          DynamicLookupInfo());
      }
  
      // Self is also valid in all cases in which it can be used in function
      // bodies. Suggest it if applicable.
      getSelfTypeCompletionInDeclContext(CodeCompletionLoc,
                                         /*isForResultType=*/false);
    }
  
    static bool canUseAttributeOnDecl(DeclAttrKind DAK, bool IsInSil,
                                      bool IsConcurrencyEnabled,
                                      bool IsDistributedEnabled,
                                      Optional<DeclKind> DK) {
      if (DeclAttribute::isUserInaccessible(DAK))
        return false;
      if (DeclAttribute::isDeclModifier(DAK))
        return false;
      if (DeclAttribute::shouldBeRejectedByParser(DAK))
        return false;
      if (!IsInSil && DeclAttribute::isSilOnly(DAK))
        return false;
      if (!IsConcurrencyEnabled && DeclAttribute::isConcurrencyOnly(DAK))
        return false;
      if (!IsDistributedEnabled && DeclAttribute::isDistributedOnly(DAK))
        return false;
      if (!DK.hasValue())
        return true;
      return DeclAttribute::canAttributeAppearOnDeclKind(DAK, DK.getValue());
    }
  
    void getAttributeDeclCompletions(bool IsInSil, Optional<DeclKind> DK) {
      // FIXME: also include user-defined attribute keywords
      StringRef TargetName = "Declaration";
      if (DK.hasValue()) {
        switch (DK.getValue()) {
  #define DECL(Id, ...)                                                         \
        case DeclKind::Id:                                                      \
          TargetName = #Id;                                                     \
          break;
  #include "swift/AST/DeclNodes.def"
        }
      }
      bool IsConcurrencyEnabled = Ctx.LangOpts.EnableExperimentalConcurrency;
      bool IsDistributedEnabled = Ctx.LangOpts.EnableExperimentalDistributed;
      std::string Description = TargetName.str() + " Attribute";
  #define DECL_ATTR(KEYWORD, NAME, ...)                                         \
      if (canUseAttributeOnDecl(DAK_##NAME, IsInSil,                            \
                                IsConcurrencyEnabled,                           \
                                IsDistributedEnabled,                           \
                                DK))                                            \
        addDeclAttrKeyword(#KEYWORD, Description);
  #include "swift/AST/Attr.def"
    }
  
    void getAttributeDeclParamCompletions(DeclAttrKind AttrKind, int ParamIndex) {
      if (AttrKind == DAK_Available) {
        if (ParamIndex == 0) {
          addDeclAttrParamKeyword("*", "Platform", false);
  
  #define AVAILABILITY_PLATFORM(X, PrettyName)                                  \
          addDeclAttrParamKeyword(swift::platformString(PlatformKind::X),       \
                                  "Platform", false);
  #include "swift/AST/PlatformKinds.def"
  
        } else {
          addDeclAttrParamKeyword("unavailable", "", false);
          addDeclAttrParamKeyword("message", "Specify message", true);
          addDeclAttrParamKeyword("renamed", "Specify replacing name", true);
          addDeclAttrParamKeyword("introduced", "Specify version number", true);
          addDeclAttrParamKeyword("deprecated", "Specify version number", true);
        }
      }
    }
  
    void getTypeAttributeKeywordCompletions() {
      auto addTypeAttr = [&](StringRef Name) {
        CodeCompletionResultBuilder Builder(
            Sink,
            CodeCompletionResult::ResultKind::Keyword,
            SemanticContextKind::None, expectedTypeContext);
        Builder.addAttributeKeyword(Name, "Type Attribute");
      };
      addTypeAttr("autoclosure");
      addTypeAttr("convention(swift)");
      addTypeAttr("convention(block)");
      addTypeAttr("convention(c)");
      addTypeAttr("convention(thin)");
      addTypeAttr("escaping");
    }
  
    void collectPrecedenceGroups() {
      assert(CurrDeclContext);
  
      if (CurrModule) {
        for (auto FU: CurrModule->getFiles()) {
          // We are looking through the current module,
          // inspect only source files.
          if (FU->getKind() != FileUnitKind::Source)
            continue;
  
          llvm::SmallVector<PrecedenceGroupDecl*, 4> results;
          cast<SourceFile>(FU)->getPrecedenceGroups(results);
  
          for (auto PG: results)
              addPrecedenceGroupRef(PG);
        }
      }
      for (auto Import : namelookup::getAllImports(CurrDeclContext)) {
        auto Module = Import.importedModule;
        if (Module == CurrModule)
          continue;
  
        RequestedCachedResults.push_back(RequestedResultsTy::fromModule(Module)
                                             .onlyPrecedenceGroups()
                                             .withModuleQualifier(false));
      }
    }
  
    void getPrecedenceGroupCompletions(SyntaxKind SK) {
      switch (SK) {
      case SyntaxKind::PrecedenceGroupAssociativity:
        addKeyword(getAssociativitySpelling(Associativity::None));
        addKeyword(getAssociativitySpelling(Associativity::Left));
        addKeyword(getAssociativitySpelling(Associativity::Right));
        break;
      case SyntaxKind::PrecedenceGroupAssignment:
        addKeyword(getTokenText(tok::kw_false), Type(), SemanticContextKind::None,
                   CodeCompletionKeywordKind::kw_false);
        addKeyword(getTokenText(tok::kw_true), Type(), SemanticContextKind::None,
                   CodeCompletionKeywordKind::kw_true);
        break;
      case SyntaxKind::PrecedenceGroupAttributeList:
        addKeyword("associativity");
        addKeyword("higherThan");
        addKeyword("lowerThan");
        addKeyword("assignment");
        break;
      case SyntaxKind::PrecedenceGroupRelation:
        collectPrecedenceGroups();
        break;
      default:
          llvm_unreachable("not a precedencegroup SyntaxKind");
      }
    }
  
    void getPoundAvailablePlatformCompletions() {
  
      // The platform names should be identical to those in @available.
      getAttributeDeclParamCompletions(DAK_Available, 0);
    }
  
    /// \p Loc is the location of the code completin token.
    /// \p isForDeclResult determines if were are spelling out the result type
    /// of a declaration.
    void getSelfTypeCompletionInDeclContext(SourceLoc Loc, bool isForDeclResult) {
      const DeclContext *typeDC = CurrDeclContext->getInnermostTypeContext();
      if (!typeDC)
        return;
  
      // For protocols, there's a 'Self' generic parameter.
      if (typeDC->getSelfProtocolDecl())
        return;
  
      Type selfType =
          CurrDeclContext->mapTypeIntoContext(typeDC->getSelfInterfaceType());
  
      if (typeDC->getSelfClassDecl()) {
        // In classes, 'Self' can be used in result type of func, subscript and
        // computed property, or inside function bodies.
        bool canUseDynamicSelf = false;
        if (isForDeclResult) {
          canUseDynamicSelf = true;
        } else {
          const auto *checkDC = CurrDeclContext;
          if (isa<TypeAliasDecl>(checkDC))
            checkDC = checkDC->getParent();
  
          if (const auto *AFD = checkDC->getInnermostMethodContext()) {
            canUseDynamicSelf = Ctx.SourceMgr.rangeContainsTokenLoc(
                AFD->getBodySourceRange(), Loc);
          }
        }
        if (!canUseDynamicSelf)
          return;
        // 'Self' in class is a dynamic type.
        selfType = DynamicSelfType::get(selfType, Ctx);
      } else {
        // In enums and structs, 'Self' is just an alias for the nominal type,
        // and can be used anywhere.
      }
  
      CodeCompletionResultBuilder Builder(
          Sink, CodeCompletionResult::ResultKind::Keyword,
          SemanticContextKind::CurrentNominal, expectedTypeContext);
      Builder.addKeyword("Self");
      Builder.setKeywordKind(CodeCompletionKeywordKind::kw_Self);
      addTypeAnnotation(Builder, selfType);
    }
  
    void getTypeCompletionsInDeclContext(SourceLoc Loc,
                                         bool ModuleQualifier = true) {
      Kind = LookupKind::TypeInDeclContext;
  
      AccessFilteringDeclConsumer AccessFilteringConsumer(
          CurrDeclContext, *this);
      lookupVisibleDecls(AccessFilteringConsumer, CurrDeclContext,
                         /*IncludeTopLevel=*/false, Loc);
  
      RequestedCachedResults.push_back(
        RequestedResultsTy::toplevelResults()
          .onlyTypes()
          .withModuleQualifier(ModuleQualifier));
    }
  
    void getToplevelCompletions(bool OnlyTypes) {
      Kind = OnlyTypes ? LookupKind::TypeInDeclContext
                       : LookupKind::ValueInDeclContext;
      NeedLeadingDot = false;
  
      UsableFilteringDeclConsumer UsableFilteringConsumer(
          Ctx.SourceMgr, CurrDeclContext, Ctx.SourceMgr.getCodeCompletionLoc(),
          *this);
      AccessFilteringDeclConsumer AccessFilteringConsumer(
          CurrDeclContext, UsableFilteringConsumer);
  
      CurrModule->lookupVisibleDecls({}, AccessFilteringConsumer,
                                     NLKind::UnqualifiedLookup);
    }
  
    void lookupExternalModuleDecls(const ModuleDecl *TheModule,
                                   ArrayRef<std::string> AccessPath,
                                   bool ResultsHaveLeadingDot) {
      assert(CurrModule != TheModule &&
             "requested module should be external");
  
      Kind = LookupKind::ImportFromModule;
      NeedLeadingDot = ResultsHaveLeadingDot;
  
      ImportPath::Access::Builder builder;
      for (auto Piece : AccessPath) {
        builder.push_back(Ctx.getIdentifier(Piece));
      }
  
      AccessFilteringDeclConsumer FilteringConsumer(CurrDeclContext, *this);
      TheModule->lookupVisibleDecls(builder.get(), FilteringConsumer,
                                    NLKind::UnqualifiedLookup);
  
      llvm::SmallVector<PrecedenceGroupDecl*, 16> precedenceGroups;
      TheModule->getPrecedenceGroups(precedenceGroups);
  
      for (auto PGD: precedenceGroups)
        addPrecedenceGroupRef(PGD);
    }
  
    void getStmtLabelCompletions(SourceLoc Loc, bool isContinue) {
      class LabelFinder : public ASTWalker {
        SourceManager &SM;
        SourceLoc TargetLoc;
        bool IsContinue;
  
      public:
        SmallVector<Identifier, 2> Result;
  
        LabelFinder(SourceManager &SM, SourceLoc TargetLoc, bool IsContinue)
            : SM(SM), TargetLoc(TargetLoc), IsContinue(IsContinue) {}
  
        std::pair<bool, Stmt *> walkToStmtPre(Stmt *S) override {
          if (SM.isBeforeInBuffer(S->getEndLoc(), TargetLoc))
            return {false, S};
  
          if (LabeledStmt *LS = dyn_cast<LabeledStmt>(S)) {
            if (LS->getLabelInfo()) {
              if (!IsContinue || LS->isPossibleContinueTarget()) {
                auto label = LS->getLabelInfo().Name;
                if (!llvm::is_contained(Result, label))
                  Result.push_back(label);
              }
            }
          }
  
          return {true, S};
        }
  
        Stmt *walkToStmtPost(Stmt *S) override { return nullptr; }
  
        std::pair<bool, Expr *> walkToExprPre(Expr *E) override {
          if (SM.isBeforeInBuffer(E->getEndLoc(), TargetLoc))
            return {false, E};
          return {true, E};
        }
      } Finder(CurrDeclContext->getASTContext().SourceMgr, Loc, isContinue);
      const_cast<DeclContext *>(CurrDeclContext)->walkContext(Finder);
      for (auto name : Finder.Result) {
        CodeCompletionResultBuilder Builder(
            Sink, CodeCompletionResult::ResultKind::Pattern,
            SemanticContextKind::Local, {});
        Builder.addTextChunk(name.str());
      }
    }
  };
  
  class CompletionOverrideLookup : public swift::VisibleDeclConsumer {
    CodeCompletionResultSink &Sink;
    ASTContext &Ctx;
    const DeclContext *CurrDeclContext;
    SmallVectorImpl<StringRef> &ParsedKeywords;
    SourceLoc introducerLoc;
  
    bool hasFuncIntroducer = false;
    bool hasVarIntroducer = false;
    bool hasTypealiasIntroducer = false;
    bool hasInitializerModifier = false;
    bool hasAccessModifier = false;
    bool hasOverride = false;
    bool hasOverridabilityModifier = false;
    bool hasStaticOrClass = false;
  
  public:
    CompletionOverrideLookup(CodeCompletionResultSink &Sink, ASTContext &Ctx,
                             const DeclContext *CurrDeclContext,
                             SmallVectorImpl<StringRef> &ParsedKeywords,
                             SourceLoc introducerLoc)
        : Sink(Sink), Ctx(Ctx), CurrDeclContext(CurrDeclContext),
          ParsedKeywords(ParsedKeywords), introducerLoc(introducerLoc) {
      hasFuncIntroducer = isKeywordSpecified("func");
      hasVarIntroducer = isKeywordSpecified("var") ||
                         isKeywordSpecified("let");
      hasTypealiasIntroducer = isKeywordSpecified("typealias");
      hasInitializerModifier = isKeywordSpecified("required") ||
                               isKeywordSpecified("convenience");
      hasAccessModifier = isKeywordSpecified("private") ||
                          isKeywordSpecified("fileprivate") ||
                          isKeywordSpecified("internal") ||
                          isKeywordSpecified("public") ||
                          isKeywordSpecified("open");
      hasOverride = isKeywordSpecified("override");
      hasOverridabilityModifier = isKeywordSpecified("final") ||
                                  isKeywordSpecified("open");
      hasStaticOrClass = isKeywordSpecified(getTokenText(tok::kw_class)) ||
                         isKeywordSpecified(getTokenText(tok::kw_static));
    }
  
    bool isKeywordSpecified(StringRef Word) {
      return std::find(ParsedKeywords.begin(), ParsedKeywords.end(), Word)
        != ParsedKeywords.end();
    }
  
    bool missingOverride(DeclVisibilityKind Reason) {
      return !hasOverride && Reason == DeclVisibilityKind::MemberOfSuper &&
             !CurrDeclContext->getSelfProtocolDecl();
    }
  
    /// Add an access modifier (i.e. `public`) to \p Builder is necessary.
    /// Returns \c true if the modifier is actually added, \c false otherwise.
    bool addAccessControl(const ValueDecl *VD,
                          CodeCompletionResultBuilder &Builder) {
      auto CurrentNominal = CurrDeclContext->getSelfNominalTypeDecl();
      assert(CurrentNominal);
  
      auto AccessOfContext = CurrentNominal->getFormalAccess();
      if (AccessOfContext < AccessLevel::Public)
        return false;
  
      auto Access = VD->getFormalAccess();
      // Use the greater access between the protocol requirement and the witness.
      // In case of:
      //
      //   public protocol P { func foo() }
      //   public class B { func foo() {} }
      //   public class C: B, P {
      //     <complete>
      //   }
      //
      // 'VD' is 'B.foo()' which is implicitly 'internal'. But as the overriding
      // declaration, the user needs to write both 'public' and 'override':
      //
      //   public class C: B {
      //     public override func foo() {}
      //   }
      if (Access < AccessLevel::Public &&
          !isa<ProtocolDecl>(VD->getDeclContext())) {
        for (auto Conformance : CurrentNominal->getAllConformances()) {
          Conformance->getRootConformance()->forEachValueWitness(
              [&](ValueDecl *req, Witness witness) {
                if (witness.getDecl() == VD)
                  Access = std::max(
                      Access, Conformance->getProtocol()->getFormalAccess());
              });
        }
      }
  
      Access = std::min(Access, AccessOfContext);
      // Only emit 'public', not needed otherwise.
      if (Access < AccessLevel::Public)
        return false;
  
      Builder.addAccessControlKeyword(Access);
      return true;
    }
  
    /// Return type if the result type if \p VD should be represented as opaque
    /// result type.
    Type getOpaqueResultType(const ValueDecl *VD, DeclVisibilityKind Reason,
                             DynamicLookupInfo dynamicLookupInfo) {
      if (Reason !=
          DeclVisibilityKind::MemberOfProtocolConformedToByCurrentNominal)
        return nullptr;
  
      auto currTy = CurrDeclContext->getDeclaredTypeInContext();
      if (!currTy)
        return nullptr;
  
      Type ResultT;
      if (auto *FD = dyn_cast<FuncDecl>(VD)) {
        if (FD->getGenericParams()) {
          // Generic function cannot have opaque result type.
          return nullptr;
        }
        ResultT = FD->getResultInterfaceType();
      } else if (auto *SD = dyn_cast<SubscriptDecl>(VD)) {
        if (SD->getGenericParams()) {
          // Generic subscript cannot have opaque result type.
          return nullptr;
        }
        ResultT = SD->getElementInterfaceType();
      } else if (auto *VarD = dyn_cast<VarDecl>(VD)) {
        ResultT = VarD->getInterfaceType();
      } else {
        return nullptr;
      }
  
      if (!ResultT->is<DependentMemberType>() ||
          !ResultT->castTo<DependentMemberType>()->getAssocType())
        // The result is not a valid associatedtype.
        return nullptr;
  
      // Try substitution to see if the associated type is resolved to concrete
      // type.
      auto substMap = currTy->getMemberSubstitutionMap(
          CurrDeclContext->getParentModule(), VD);
      if (!ResultT.subst(substMap)->is<DependentMemberType>())
        // If resolved print it.
        return nullptr;
  
      auto genericSig = VD->getDeclContext()->getGenericSignatureOfContext();
  
      if (genericSig->isConcreteType(ResultT))
        // If it has same type requrement, we will emit the concrete type.
        return nullptr;
  
      // Collect requirements on the associatedtype.
      SmallVector<Type, 2> opaqueTypes;
      bool hasExplicitAnyObject = false;
      if (auto superTy = genericSig->getSuperclassBound(ResultT))
        opaqueTypes.push_back(superTy);
      for (const auto proto : genericSig->getRequiredProtocols(ResultT))
        opaqueTypes.push_back(proto->getDeclaredInterfaceType());
      if (auto layout = genericSig->getLayoutConstraint(ResultT))
        hasExplicitAnyObject = layout->isClass();
  
      if (!hasExplicitAnyObject) {
        if (opaqueTypes.empty())
          return nullptr;
        if (opaqueTypes.size() == 1)
          return opaqueTypes.front();
      }
      return ProtocolCompositionType::get(
          VD->getASTContext(), opaqueTypes, hasExplicitAnyObject);
    }
  
    void addValueOverride(const ValueDecl *VD, DeclVisibilityKind Reason,
                          DynamicLookupInfo dynamicLookupInfo,
                          CodeCompletionResultBuilder &Builder,
                          bool hasDeclIntroducer) {
      Type opaqueResultType = getOpaqueResultType(VD, Reason, dynamicLookupInfo);
  
      class DeclPrinter : public CodeCompletionStringPrinter {
        Type OpaqueBaseTy;
  
      public:
        DeclPrinter(CodeCompletionResultBuilder &Builder, Type OpaqueBaseTy)
            : CodeCompletionStringPrinter(Builder), OpaqueBaseTy(OpaqueBaseTy) { }
  
        // As for FuncDecl, SubscriptDecl, and VarDecl, substitute the result type
        // with 'OpaqueBaseTy' if specified.
        void printDeclResultTypePre(ValueDecl *VD, TypeLoc &TL) override {
          if (!OpaqueBaseTy.isNull()) {
            setNextChunkKind(ChunkKind::Keyword);
            printText("some ");
            setNextChunkKind(ChunkKind::Text);
            TL = TypeLoc::withoutLoc(OpaqueBaseTy);
          }
          CodeCompletionStringPrinter::printDeclResultTypePre(VD, TL);
        }
      };
  
      DeclPrinter Printer(Builder, opaqueResultType);
      Printer.startPreamble();
  
      bool modifierAdded = false;
  
      // 'public' if needed.
      modifierAdded |= !hasAccessModifier && addAccessControl(VD, Builder);
  
      // 'override' if needed
      if (missingOverride(Reason)) {
        Builder.addOverrideKeyword();
        modifierAdded |= true;
      }
  
      // Erase existing introducer (e.g. 'func') if any modifiers are added.
      if (hasDeclIntroducer && modifierAdded) {
        auto dist = Ctx.SourceMgr.getByteDistance(
            introducerLoc, Ctx.SourceMgr.getCodeCompletionLoc());
        if (dist <= CodeCompletionResult::MaxNumBytesToErase) {
          Builder.setNumBytesToErase(dist);
          hasDeclIntroducer = false;
        }
      }
  
      PrintOptions PO;
      if (auto transformType = CurrDeclContext->getDeclaredTypeInContext())
        PO.setBaseType(transformType);
      PO.PrintPropertyAccessors = false;
      PO.PrintSubscriptAccessors = false;
  
      PO.SkipUnderscoredKeywords = true;
      PO.PrintImplicitAttrs = false;
      PO.ExclusiveAttrList.push_back(TAK_escaping);
      PO.ExclusiveAttrList.push_back(TAK_autoclosure);
      // Print certain modifiers only when the introducer is not written.
      // Otherwise, the user can add it after the completion.
      if (!hasDeclIntroducer) {
        PO.ExclusiveAttrList.push_back(DAK_Nonisolated);
      }
  
      PO.PrintAccess = false;
      PO.PrintOverrideKeyword = false;
      PO.PrintSelfAccessKindKeyword = false;
  
      PO.PrintStaticKeyword = !hasStaticOrClass && !hasDeclIntroducer;
      PO.SkipIntroducerKeywords = hasDeclIntroducer;
      VD->print(Printer, PO);
    }
  
    void addMethodOverride(const FuncDecl *FD, DeclVisibilityKind Reason,
                           DynamicLookupInfo dynamicLookupInfo) {
      CodeCompletionResultBuilder Builder(
          Sink, CodeCompletionResult::ResultKind::Declaration,
          SemanticContextKind::Super, {});
      Builder.setExpectedTypeRelation(
          CodeCompletionResult::ExpectedTypeRelation::NotApplicable);
      Builder.setAssociatedDecl(FD);
      addValueOverride(FD, Reason, dynamicLookupInfo, Builder, hasFuncIntroducer);
      Builder.addBraceStmtWithCursor();
    }
  
    void addVarOverride(const VarDecl *VD, DeclVisibilityKind Reason,
                        DynamicLookupInfo dynamicLookupInfo) {
      // Overrides cannot use 'let', but if the 'override' keyword is specified
      // then the intention is clear, so provide the results anyway.  The compiler
      // can then provide an error telling you to use 'var' instead.
      // If we don't need override then it's a protocol requirement, so show it.
      if (missingOverride(Reason) && hasVarIntroducer &&
          isKeywordSpecified("let"))
        return;
  
      CodeCompletionResultBuilder Builder(
          Sink, CodeCompletionResult::ResultKind::Declaration,
          SemanticContextKind::Super, {});
      Builder.setAssociatedDecl(VD);
      addValueOverride(VD, Reason, dynamicLookupInfo, Builder, hasVarIntroducer);
    }
  
    void addSubscriptOverride(const SubscriptDecl *SD, DeclVisibilityKind Reason,
                              DynamicLookupInfo dynamicLookupInfo) {
      CodeCompletionResultBuilder Builder(
          Sink, CodeCompletionResult::ResultKind::Declaration,
          SemanticContextKind::Super, {});
      Builder.setExpectedTypeRelation(
          CodeCompletionResult::ExpectedTypeRelation::NotApplicable);
      Builder.setAssociatedDecl(SD);
      addValueOverride(SD, Reason, dynamicLookupInfo, Builder, false);
      Builder.addBraceStmtWithCursor();
    }
  
    void addTypeAlias(const AssociatedTypeDecl *ATD, DeclVisibilityKind Reason,
                      DynamicLookupInfo dynamicLookupInfo) {
      CodeCompletionResultBuilder Builder(Sink,
        CodeCompletionResult::ResultKind::Declaration,
        SemanticContextKind::Super, {});
      Builder.setExpectedTypeRelation(
          CodeCompletionResult::ExpectedTypeRelation::NotApplicable);
      Builder.setAssociatedDecl(ATD);
      if (!hasTypealiasIntroducer && !hasAccessModifier)
        (void)addAccessControl(ATD, Builder);
      if (!hasTypealiasIntroducer)
        Builder.addDeclIntroducer("typealias ");
      Builder.addBaseName(ATD->getName().str());
      Builder.addTextChunk(" = ");
      Builder.addSimpleNamedParameter("Type");
    }
  
    void addConstructor(const ConstructorDecl *CD, DeclVisibilityKind Reason,
                        DynamicLookupInfo dynamicLookupInfo) {
      CodeCompletionResultBuilder Builder(
          Sink,
          CodeCompletionResult::ResultKind::Declaration,
          SemanticContextKind::Super, {});
      Builder.setExpectedTypeRelation(
          CodeCompletionResult::ExpectedTypeRelation::NotApplicable);
      Builder.setAssociatedDecl(CD);
  
      CodeCompletionStringPrinter printer(Builder);
      printer.startPreamble();
  
      if (!hasAccessModifier)
        (void)addAccessControl(CD, Builder);
  
      if (missingOverride(Reason) && CD->isDesignatedInit() && !CD->isRequired())
        Builder.addOverrideKeyword();
  
      // Emit 'required' if we're in class context, 'required' is not specified,
      // and 1) this is a protocol conformance and the class is not final, or 2)
      // this is subclass and the initializer is marked as required.
      bool needRequired = false;
      auto C = CurrDeclContext->getSelfClassDecl();
      if (C && !isKeywordSpecified("required")) {
        switch (Reason) {
        case DeclVisibilityKind::MemberOfProtocolConformedToByCurrentNominal:
        case DeclVisibilityKind::MemberOfProtocolDerivedByCurrentNominal:
          if (!C->isSemanticallyFinal())
            needRequired = true;
          break;
        case DeclVisibilityKind::MemberOfSuper:
          if (CD->isRequired())
            needRequired = true;
          break;
        default: break;
        }
      }
      if (needRequired)
        Builder.addRequiredKeyword();
  
      {
        PrintOptions Options;
        if (auto transformType = CurrDeclContext->getDeclaredTypeInContext())
          Options.setBaseType(transformType);
        Options.PrintImplicitAttrs = false;
        Options.SkipAttributes = true;
        CD->print(printer, Options);
      }
      printer.flush();
  
      Builder.addBraceStmtWithCursor();
    }
  
    // Implement swift::VisibleDeclConsumer.
    void foundDecl(ValueDecl *D, DeclVisibilityKind Reason,
                   DynamicLookupInfo dynamicLookupInfo) override {
      if (Reason == DeclVisibilityKind::MemberOfCurrentNominal)
        return;
  
      if (D->shouldHideFromEditor())
        return;
  
      if (D->isSemanticallyFinal())
        return;
  
      bool hasIntroducer = hasFuncIntroducer ||
                           hasVarIntroducer ||
                           hasTypealiasIntroducer;
  
      if (hasStaticOrClass && !D->isStatic())
        return;
  
      // As per the current convention, only instance members are
      // suggested if an introducer is not accompanied by a 'static' or
      // 'class' modifier.
      if (hasIntroducer && !hasStaticOrClass && D->isStatic())
        return;
  
      if (auto *FD = dyn_cast<FuncDecl>(D)) {
        // We cannot override operators as members.
        if (FD->isBinaryOperator() || FD->isUnaryOperator())
          return;
  
        // We cannot override individual accessors.
        if (isa<AccessorDecl>(FD))
          return;
  
        if (hasFuncIntroducer || (!hasIntroducer && !hasInitializerModifier))
          addMethodOverride(FD, Reason, dynamicLookupInfo);
        return;
      }
  
      if (auto *VD = dyn_cast<VarDecl>(D)) {
        if (hasVarIntroducer || (!hasIntroducer && !hasInitializerModifier))
          addVarOverride(VD, Reason, dynamicLookupInfo);
        return;
      }
  
      if (auto *SD = dyn_cast<SubscriptDecl>(D)) {
        if (!hasIntroducer && !hasInitializerModifier)
          addSubscriptOverride(SD, Reason, dynamicLookupInfo);
      }
  
      if (auto *CD = dyn_cast<ConstructorDecl>(D)) {
        if (!isa<ProtocolDecl>(CD->getDeclContext()))
          return;
        if (hasIntroducer || hasOverride || hasOverridabilityModifier ||
            hasStaticOrClass)
          return;
        if (CD->isRequired() || CD->isDesignatedInit())
          addConstructor(CD, Reason, dynamicLookupInfo);
        return;
      }
    }
  
    void addDesignatedInitializers(NominalTypeDecl *NTD) {
      if (hasFuncIntroducer || hasVarIntroducer || hasTypealiasIntroducer ||
          hasOverridabilityModifier || hasStaticOrClass)
        return;
  
      const auto *CD = dyn_cast<ClassDecl>(NTD);
      if (!CD)
        return;
      if (!CD->hasSuperclass())
        return;
      CD = CD->getSuperclassDecl();
      for (const auto *Member : CD->getMembers()) {
        const auto *Constructor = dyn_cast<ConstructorDecl>(Member);
        if (!Constructor)
          continue;
        if (Constructor->hasStubImplementation())
          continue;
        if (Constructor->isDesignatedInit())
          addConstructor(Constructor, DeclVisibilityKind::MemberOfSuper, {});
      }
    }
  
    void addAssociatedTypes(NominalTypeDecl *NTD) {
      if (!hasTypealiasIntroducer &&
          (hasFuncIntroducer || hasVarIntroducer || hasInitializerModifier ||
           hasOverride || hasOverridabilityModifier || hasStaticOrClass))
        return;
  
      for (auto Conformance : NTD->getAllConformances()) {
        auto Proto = Conformance->getProtocol();
        if (!Proto->isAccessibleFrom(CurrDeclContext))
          continue;
        for (auto *ATD : Proto->getAssociatedTypeMembers()) {
          // FIXME: Also exclude the type alias that has already been specified.
          if (!Conformance->hasTypeWitness(ATD) ||
              ATD->hasDefaultDefinitionType())
            continue;
          addTypeAlias(
              ATD,
              DeclVisibilityKind::MemberOfProtocolConformedToByCurrentNominal,
              {});
        }
      }
    }
  
    static StringRef getResultBuilderDocComment(
        ResultBuilderBuildFunction function) {
      switch (function) {
      case ResultBuilderBuildFunction::BuildArray:
        return "Enables support for..in loops in a result builder by "
          "combining the results of all iterations into a single result";
  
      case ResultBuilderBuildFunction::BuildBlock:
        return "Required by every result builder to build combined results "
            "from statement blocks";
  
      case ResultBuilderBuildFunction::BuildEitherFirst:
        return "With buildEither(second:), enables support for 'if-else' and "
            "'switch' statements by folding conditional results into a single "
            "result";
  
      case ResultBuilderBuildFunction::BuildEitherSecond:
        return "With buildEither(first:), enables support for 'if-else' and "
            "'switch' statements by folding conditional results into a single "
            "result";
  
      case ResultBuilderBuildFunction::BuildExpression:
        return "If declared, provides contextual type information for statement "
            "expressions to translate them into partial results";
  
      case ResultBuilderBuildFunction::BuildFinalResult:
        return "If declared, this will be called on the partial result from the "
            "outermost block statement to produce the final returned result";
  
      case ResultBuilderBuildFunction::BuildLimitedAvailability:
        return "If declared, this will be called on the partial result of "
          "an 'if #available' block to allow the result builder to erase "
          "type information";
  
      case ResultBuilderBuildFunction::BuildOptional:
        return "Enables support for `if` statements that do not have an `else`";
      }
    }
  
    void addResultBuilderBuildCompletion(
        NominalTypeDecl *builder, Type componentType,
        ResultBuilderBuildFunction function) {
      CodeCompletionResultBuilder Builder(
          Sink,
          CodeCompletionResult::ResultKind::Pattern,
          SemanticContextKind::CurrentNominal, {});
      Builder.setExpectedTypeRelation(
          CodeCompletionResult::ExpectedTypeRelation::NotApplicable);
  
      if (!hasFuncIntroducer) {
        if (!hasAccessModifier &&
            builder->getFormalAccess() >= AccessLevel::Public)
          Builder.addAccessControlKeyword(AccessLevel::Public);
  
        if (!hasStaticOrClass)
          Builder.addTextChunk("static ");
  
        Builder.addTextChunk("func ");
      }
  
      std::string declStringWithoutFunc;
      {
        llvm::raw_string_ostream out(declStringWithoutFunc);
        printResultBuilderBuildFunction(
            builder, componentType, function, None, out);
      }
      Builder.addTextChunk(declStringWithoutFunc);
      Builder.addBraceStmtWithCursor();
      Builder.setBriefDocComment(getResultBuilderDocComment(function));
    }
  
    /// Add completions for the various "build" functions in a result builder.
    void addResultBuilderBuildCompletions(NominalTypeDecl *builder) {
      Type componentType = inferResultBuilderComponentType(builder);
  
      addResultBuilderBuildCompletion(
          builder, componentType, ResultBuilderBuildFunction::BuildBlock);
      addResultBuilderBuildCompletion(
          builder, componentType, ResultBuilderBuildFunction::BuildExpression);
      addResultBuilderBuildCompletion(
          builder, componentType, ResultBuilderBuildFunction::BuildOptional);
      addResultBuilderBuildCompletion(
          builder, componentType, ResultBuilderBuildFunction::BuildEitherFirst);
      addResultBuilderBuildCompletion(
          builder, componentType, ResultBuilderBuildFunction::BuildEitherSecond);
      addResultBuilderBuildCompletion(
          builder, componentType, ResultBuilderBuildFunction::BuildArray);
      addResultBuilderBuildCompletion(
          builder, componentType,
          ResultBuilderBuildFunction::BuildLimitedAvailability);
      addResultBuilderBuildCompletion(
          builder, componentType, ResultBuilderBuildFunction::BuildFinalResult);
    }
  
    void getOverrideCompletions(SourceLoc Loc) {
      if (!CurrDeclContext->isTypeContext())
        return;
      if (isa<ProtocolDecl>(CurrDeclContext))
        return;
  
      Type CurrTy = CurrDeclContext->getSelfTypeInContext();
      auto *NTD = CurrDeclContext->getSelfNominalTypeDecl();
      if (CurrTy && !CurrTy->is<ErrorType>()) {
        // Look for overridable static members too.
        Type Meta = MetatypeType::get(CurrTy);
        lookupVisibleMemberDecls(*this, Meta, CurrDeclContext,
                                 /*includeInstanceMembers=*/true,
                                 /*includeDerivedRequirements*/true,
                                 /*includeProtocolExtensionMembers*/false);
        addDesignatedInitializers(NTD);
        addAssociatedTypes(NTD);
      }
  
      if (NTD && NTD->getAttrs().hasAttribute<ResultBuilderAttr>()) {
        addResultBuilderBuildCompletions(NTD);
      }
    }
  };
  } // end anonymous namespace
  
  static void addSelectorModifierKeywords(CodeCompletionResultSink &sink) {
    auto addKeyword = [&](StringRef Name, CodeCompletionKeywordKind Kind) {
      CodeCompletionResultBuilder Builder(
                                    sink,
                                    CodeCompletionResult::ResultKind::Keyword,
                                    SemanticContextKind::None, {});
      Builder.setKeywordKind(Kind);
      Builder.addTextChunk(Name);
      Builder.addCallParameterColon();
      Builder.addSimpleTypedParameter("@objc property", /*IsVarArg=*/false);
    };
  
    addKeyword("getter", CodeCompletionKeywordKind::None);
    addKeyword("setter", CodeCompletionKeywordKind::None);
  }
  
  void CodeCompletionCallbacksImpl::completeDotExpr(CodeCompletionExpr *E,
                                                    SourceLoc DotLoc) {
    assert(P.Tok.is(tok::code_complete));
  
    // Don't produce any results in an enum element.
    if (InEnumElementRawValue)
      return;
  
    Kind = CompletionKind::DotExpr;
    if (ParseExprSelectorContext != ObjCSelectorContext::None) {
      PreferFunctionReferencesToCalls = true;
      CompleteExprSelectorContext = ParseExprSelectorContext;
    }
  
    ParsedExpr = E->getBase();
    this->DotLoc = DotLoc;
    CurDeclContext = P.CurDeclContext;
    CodeCompleteTokenExpr = E;
  }
  
  void CodeCompletionCallbacksImpl::completeStmtOrExpr(CodeCompletionExpr *E) {
    assert(P.Tok.is(tok::code_complete));
    Kind = CompletionKind::StmtOrExpr;
    CurDeclContext = P.CurDeclContext;
    CodeCompleteTokenExpr = E;
  }
  
  void CodeCompletionCallbacksImpl::completePostfixExprBeginning(CodeCompletionExpr *E) {
    assert(P.Tok.is(tok::code_complete));
  
    // Don't produce any results in an enum element.
    if (InEnumElementRawValue)
      return;
  
    Kind = CompletionKind::PostfixExprBeginning;
    if (ParseExprSelectorContext != ObjCSelectorContext::None) {
      PreferFunctionReferencesToCalls = true;
      CompleteExprSelectorContext = ParseExprSelectorContext;
      if (CompleteExprSelectorContext == ObjCSelectorContext::MethodSelector) {
        addSelectorModifierKeywords(CompletionContext.getResultSink());
      }
    }
  
  
    CurDeclContext = P.CurDeclContext;
    CodeCompleteTokenExpr = E;
  }
  
  void CodeCompletionCallbacksImpl::completeForEachSequenceBeginning(
      CodeCompletionExpr *E) {
    assert(P.Tok.is(tok::code_complete));
    Kind = CompletionKind::ForEachSequence;
    CurDeclContext = P.CurDeclContext;
    CodeCompleteTokenExpr = E;
  }
  
  void CodeCompletionCallbacksImpl::completePostfixExpr(Expr *E, bool hasSpace) {
    assert(P.Tok.is(tok::code_complete));
  
    // Don't produce any results in an enum element.
    if (InEnumElementRawValue)
      return;
  
    HasSpace = hasSpace;
    Kind = CompletionKind::PostfixExpr;
    if (ParseExprSelectorContext != ObjCSelectorContext::None) {
      PreferFunctionReferencesToCalls = true;
      CompleteExprSelectorContext = ParseExprSelectorContext;
    }
  
    ParsedExpr = E;
    CurDeclContext = P.CurDeclContext;
  }
  
  void CodeCompletionCallbacksImpl::completePostfixExprParen(Expr *E,
                                                             Expr *CodeCompletionE) {
    assert(P.Tok.is(tok::code_complete));
  
    // Don't produce any results in an enum element.
    if (InEnumElementRawValue)
      return;
  
    Kind = CompletionKind::PostfixExprParen;
    ParsedExpr = E;
    CurDeclContext = P.CurDeclContext;
    CodeCompleteTokenExpr = static_cast<CodeCompletionExpr*>(CodeCompletionE);
  
    ShouldCompleteCallPatternAfterParen = true;
    if (CompletionContext.getCallPatternHeuristics()) {
      // Lookahead one token to decide what kind of call completions to provide.
      // When it appears that there is already code for the call present, just
      // complete values and/or argument labels.  Otherwise give the entire call
      // pattern.
      Token next = P.peekToken();
      if (!next.isAtStartOfLine() && !next.is(tok::eof) && !next.is(tok::r_paren)) {
        ShouldCompleteCallPatternAfterParen = false;
      }
    }
  }
  
  void CodeCompletionCallbacksImpl::completeExprKeyPath(KeyPathExpr *KPE,
                                                        SourceLoc DotLoc) {
    Kind = (!KPE || KPE->isObjC()) ? CompletionKind::KeyPathExprObjC
                                   : CompletionKind::KeyPathExprSwift;
    ParsedExpr = KPE;
    this->DotLoc = DotLoc;
    CurDeclContext = P.CurDeclContext;
  }
  
  void CodeCompletionCallbacksImpl::completePoundAvailablePlatform() {
    Kind = CompletionKind::PoundAvailablePlatform;
    CurDeclContext = P.CurDeclContext;
  }
  
  void CodeCompletionCallbacksImpl::completeTypeDeclResultBeginning() {
    Kind = CompletionKind::TypeDeclResultBeginning;
    CurDeclContext = P.CurDeclContext;
  }
  
  void CodeCompletionCallbacksImpl::completeTypeSimpleBeginning() {
    Kind = CompletionKind::TypeSimpleBeginning;
    CurDeclContext = P.CurDeclContext;
  }
  
  void CodeCompletionCallbacksImpl::completeDeclAttrParam(DeclAttrKind DK,
                                                          int Index) {
    Kind = CompletionKind::AttributeDeclParen;
    AttrKind = DK;
    AttrParamIndex = Index;
    CurDeclContext = P.CurDeclContext;
  }
  
  void CodeCompletionCallbacksImpl::completeEffectsSpecifier(bool hasAsync,
                                                             bool hasThrows) {
    Kind = CompletionKind::EffectsSpecifier;
    CurDeclContext = P.CurDeclContext;
    ParsedKeywords.clear();
    if (hasAsync)
      ParsedKeywords.emplace_back("async");
    if (hasThrows)
      ParsedKeywords.emplace_back("throws");
  }
  
  void CodeCompletionCallbacksImpl::completeDeclAttrBeginning(
      bool Sil, bool isIndependent) {
    Kind = CompletionKind::AttributeBegin;
    IsInSil = Sil;
    CurDeclContext = P.CurDeclContext;
    AttTargetIsIndependent = isIndependent;
  }
  
  void CodeCompletionCallbacksImpl::completeInPrecedenceGroup(SyntaxKind SK) {
    assert(P.Tok.is(tok::code_complete));
  
    SyntxKind = SK;
    Kind = CompletionKind::PrecedenceGroup;
    CurDeclContext = P.CurDeclContext;
  }
  
  void CodeCompletionCallbacksImpl::completeTypeIdentifierWithDot(
      IdentTypeRepr *ITR) {
    if (!ITR) {
      completeTypeSimpleBeginning();
      return;
    }
    Kind = CompletionKind::TypeIdentifierWithDot;
    ParsedTypeLoc = TypeLoc(ITR);
    CurDeclContext = P.CurDeclContext;
  }
  
  void CodeCompletionCallbacksImpl::completeTypeIdentifierWithoutDot(
      IdentTypeRepr *ITR) {
    assert(ITR);
    Kind = CompletionKind::TypeIdentifierWithoutDot;
    ParsedTypeLoc = TypeLoc(ITR);
    CurDeclContext = P.CurDeclContext;
  }
  
  void CodeCompletionCallbacksImpl::completeCaseStmtKeyword() {
    Kind = CompletionKind::CaseStmtKeyword;
    CurDeclContext = P.CurDeclContext;
  }
  
  void CodeCompletionCallbacksImpl::completeCaseStmtBeginning(CodeCompletionExpr *E) {
    assert(!InEnumElementRawValue);
  
    Kind = CompletionKind::CaseStmtBeginning;
    CurDeclContext = P.CurDeclContext;
    CodeCompleteTokenExpr = E;
  }
  
  void CodeCompletionCallbacksImpl::completeImportDecl(
      ImportPath::Builder &Path) {
    Kind = CompletionKind::Import;
    CurDeclContext = P.CurDeclContext;
    DotLoc = Path.empty() ? SourceLoc() : Path.back().Loc;
    if (DotLoc.isInvalid())
      return;
    auto Importer = static_cast<ClangImporter *>(CurDeclContext->getASTContext().
                                                 getClangModuleLoader());
    std::vector<std::string> SubNames;
    Importer->collectSubModuleNames(Path.get().getModulePath(false), SubNames);
    ASTContext &Ctx = CurDeclContext->getASTContext();
    Path.push_back(Identifier());
    for (StringRef Sub : SubNames) {
      Path.back().Item = Ctx.getIdentifier(Sub);
      SubModuleNameVisibilityPairs.push_back(
        std::make_pair(Sub.str(),
                       Ctx.getLoadedModule(Path.get().getModulePath(false))));
    }
    Path.pop_back();
  }
  
  void CodeCompletionCallbacksImpl::completeUnresolvedMember(CodeCompletionExpr *E,
      SourceLoc DotLoc) {
    Kind = CompletionKind::UnresolvedMember;
    CurDeclContext = P.CurDeclContext;
    CodeCompleteTokenExpr = E;
    this->DotLoc = DotLoc;
  }
  
  void CodeCompletionCallbacksImpl::completeCallArg(CodeCompletionExpr *E,
                                                    bool isFirst) {
    CurDeclContext = P.CurDeclContext;
    CodeCompleteTokenExpr = E;
    Kind = CompletionKind::CallArg;
  
    ShouldCompleteCallPatternAfterParen = false;
    if (isFirst) {
      ShouldCompleteCallPatternAfterParen = true;
      if (CompletionContext.getCallPatternHeuristics()) {
        // Lookahead one token to decide what kind of call completions to provide.
        // When it appears that there is already code for the call present, just
        // complete values and/or argument labels.  Otherwise give the entire call
        // pattern.
        Token next = P.peekToken();
        if (!next.isAtStartOfLine() && !next.is(tok::eof) && !next.is(tok::r_paren)) {
          ShouldCompleteCallPatternAfterParen = false;
        }
      }
    }
  }
  
  void CodeCompletionCallbacksImpl::completeLabeledTrailingClosure(
      CodeCompletionExpr *E, bool isAtStartOfLine) {
    CurDeclContext = P.CurDeclContext;
    CodeCompleteTokenExpr = E;
    Kind = CompletionKind::LabeledTrailingClosure;
    IsAtStartOfLine = isAtStartOfLine;
  }
  
  void CodeCompletionCallbacksImpl::completeReturnStmt(CodeCompletionExpr *E) {
    CurDeclContext = P.CurDeclContext;
    CodeCompleteTokenExpr = E;
    Kind = CompletionKind::ReturnStmtExpr;
  }
  
  void CodeCompletionCallbacksImpl::completeYieldStmt(CodeCompletionExpr *E,
                                                      Optional<unsigned> index) {
    CurDeclContext = P.CurDeclContext;
    CodeCompleteTokenExpr = E;
    // TODO: use a different completion kind when completing without an index
    // in a multiple-value context.
    Kind = CompletionKind::YieldStmtExpr;
  }
  
  void CodeCompletionCallbacksImpl::completeAfterPoundExpr(
      CodeCompletionExpr *E, Optional<StmtKind> ParentKind) {
    CurDeclContext = P.CurDeclContext;
    CodeCompleteTokenExpr = E;
    Kind = CompletionKind::AfterPoundExpr;
    ParentStmtKind = ParentKind;
  }
  
  void CodeCompletionCallbacksImpl::completeAfterPoundDirective() {
    CurDeclContext = P.CurDeclContext;
    Kind = CompletionKind::AfterPoundDirective;
  }
  
  void CodeCompletionCallbacksImpl::completePlatformCondition() {
    CurDeclContext = P.CurDeclContext;
    Kind = CompletionKind::PlatformConditon;
  }
  
  void CodeCompletionCallbacksImpl::completeAfterIfStmt(bool hasElse) {
    CurDeclContext = P.CurDeclContext;
    if (hasElse) {
      Kind = CompletionKind::AfterIfStmtElse;
    } else {
      Kind = CompletionKind::StmtOrExpr;
    }
  }
  
  void CodeCompletionCallbacksImpl::completeGenericRequirement() {
    CurDeclContext = P.CurDeclContext;
    Kind = CompletionKind::GenericRequirement;
  }
  
  void CodeCompletionCallbacksImpl::completeNominalMemberBeginning(
      SmallVectorImpl<StringRef> &Keywords, SourceLoc introducerLoc) {
    assert(!InEnumElementRawValue);
    this->introducerLoc = introducerLoc;
    ParsedKeywords.clear();
    ParsedKeywords.append(Keywords.begin(), Keywords.end());
    Kind = CompletionKind::NominalMemberBeginning;
    CurDeclContext = P.CurDeclContext;
  }
  
  void CodeCompletionCallbacksImpl::completeAccessorBeginning(
      CodeCompletionExpr *E) {
    Kind = CompletionKind::AccessorBeginning;
    CurDeclContext = P.CurDeclContext;
    CodeCompleteTokenExpr = E;
  }
  
  void CodeCompletionCallbacksImpl::completeStmtLabel(StmtKind ParentKind) {
    CurDeclContext = P.CurDeclContext;
    Kind = CompletionKind::StmtLabel;
    ParentStmtKind = ParentKind;
  }
  
  void CodeCompletionCallbacksImpl::completeForEachPatternBeginning(
      bool hasTry, bool hasAwait) {
    CurDeclContext = P.CurDeclContext;
    Kind = CompletionKind::ForEachPatternBeginning;
    ParsedKeywords.clear();
    if (hasTry)
      ParsedKeywords.emplace_back("try");
    if (hasAwait)
      ParsedKeywords.emplace_back("await");
  }
  
  void CodeCompletionCallbacksImpl::completeTypeAttrBeginning() {
    CurDeclContext = P.CurDeclContext;
    Kind = CompletionKind::TypeAttrBeginning;
  }
  
  static bool isDynamicLookup(Type T) {
    return T->getRValueType()->isAnyObject();
  }
  
  static bool isClangSubModule(ModuleDecl *TheModule) {
    if (auto ClangMod = TheModule->findUnderlyingClangModule())
      return ClangMod->isSubModule();
    return false;
  }
  
  static void
  addKeyword(CodeCompletionResultSink &Sink, StringRef Name,
             CodeCompletionKeywordKind Kind, StringRef TypeAnnotation = "",
             CodeCompletionResult::ExpectedTypeRelation TypeRelation =
                 CodeCompletionResult::ExpectedTypeRelation::NotApplicable,
             CodeCompletionFlair Flair = {}) {
    CodeCompletionResultBuilder Builder(Sink,
                                        CodeCompletionResult::ResultKind::Keyword,
                                        SemanticContextKind::None, {});
    Builder.setKeywordKind(Kind);
    Builder.addKeyword(Name);
    Builder.addFlair(Flair);
    if (!TypeAnnotation.empty())
      Builder.addTypeAnnotation(TypeAnnotation);
    Builder.setExpectedTypeRelation(TypeRelation);
  }
  
  static void addDeclKeywords(CodeCompletionResultSink &Sink, DeclContext *DC,
                              bool IsConcurrencyEnabled,
                              bool IsDistributedEnabled) {
    auto isTypeDeclIntroducer = [](CodeCompletionKeywordKind Kind,
                                   Optional<DeclAttrKind> DAK) -> bool {
      switch (Kind) {
      case CodeCompletionKeywordKind::kw_protocol:
      case CodeCompletionKeywordKind::kw_class:
      case CodeCompletionKeywordKind::kw_struct:
      case CodeCompletionKeywordKind::kw_enum:
      case CodeCompletionKeywordKind::kw_extension:
        return true;
      case CodeCompletionKeywordKind::None:
        if (DAK && *DAK == DeclAttrKind::DAK_Actor) {
          return true;
        }
        break;
      default:
        break;
      }
      return false;
    };
    auto isTopLevelOnlyDeclIntroducer = [](CodeCompletionKeywordKind Kind,
                                           Optional<DeclAttrKind> DAK) -> bool {
      switch (Kind) {
      case CodeCompletionKeywordKind::kw_operator:
      case CodeCompletionKeywordKind::kw_precedencegroup:
      case CodeCompletionKeywordKind::kw_import:
      case CodeCompletionKeywordKind::kw_protocol:
      case CodeCompletionKeywordKind::kw_extension:
        return true;
      default:
        return false;
      }
    };
  
    auto getFlair = [&](CodeCompletionKeywordKind Kind,
                        Optional<DeclAttrKind> DAK) -> CodeCompletionFlair {
      if (isCodeCompletionAtTopLevelOfLibraryFile(DC)) {
        // Type decls are common in library file top-level.
        if (isTypeDeclIntroducer(Kind, DAK))
          return CodeCompletionFlairBit::CommonKeywordAtCurrentPosition;
      }
      if (isa<ProtocolDecl>(DC)) {
        // Protocols cannot have nested type decls (other than 'typealias').
        if (isTypeDeclIntroducer(Kind, DAK))
          return CodeCompletionFlairBit::RareKeywordAtCurrentPosition;
      }
      if (DC->isTypeContext()) {
        // Top-level only decls are invalid in type context.
        if (isTopLevelOnlyDeclIntroducer(Kind, DAK))
          return CodeCompletionFlairBit::RareKeywordAtCurrentPosition;
      }
      if (isCompletionDeclContextLocalContext(DC)) {
        // Local type decl are valid, but not common.
        if (isTypeDeclIntroducer(Kind, DAK))
          return CodeCompletionFlairBit::RareKeywordAtCurrentPosition;
  
        // Top-level only decls are invalid in function body.
        if (isTopLevelOnlyDeclIntroducer(Kind, DAK))
          return CodeCompletionFlairBit::RareKeywordAtCurrentPosition;
  
        // 'init', 'deinit' and 'subscript' are invalid in function body.
        // Access control modifiers are invalid in function body.
        switch (Kind) {
        case CodeCompletionKeywordKind::kw_init:
        case CodeCompletionKeywordKind::kw_deinit:
        case CodeCompletionKeywordKind::kw_subscript:
        case CodeCompletionKeywordKind::kw_private:
        case CodeCompletionKeywordKind::kw_fileprivate:
        case CodeCompletionKeywordKind::kw_internal:
        case CodeCompletionKeywordKind::kw_public:
        case CodeCompletionKeywordKind::kw_static:
          return CodeCompletionFlairBit::RareKeywordAtCurrentPosition;
  
        default:
          break;
        }
  
        // These modifiers are invalid for decls in function body.
        if (DAK) {
          switch (*DAK) {
          case DeclAttrKind::DAK_Lazy:
          case DeclAttrKind::DAK_Final:
          case DeclAttrKind::DAK_Infix:
          case DeclAttrKind::DAK_Frozen:
          case DeclAttrKind::DAK_Prefix:
          case DeclAttrKind::DAK_Postfix:
          case DeclAttrKind::DAK_Dynamic:
          case DeclAttrKind::DAK_Override:
          case DeclAttrKind::DAK_Optional:
          case DeclAttrKind::DAK_Required:
          case DeclAttrKind::DAK_Convenience:
          case DeclAttrKind::DAK_AccessControl:
          case DeclAttrKind::DAK_Nonisolated:
            return CodeCompletionFlairBit::RareKeywordAtCurrentPosition;
  
          default:
            break;
          }
        }
      }
      return None;
    };
  
    auto AddDeclKeyword = [&](StringRef Name, CodeCompletionKeywordKind Kind,
                              Optional<DeclAttrKind> DAK) {
      if (Name == "let" || Name == "var") {
        // Treat keywords that could be the start of a pattern specially.
        return;
      }
  
      // FIXME: This should use canUseAttributeOnDecl.
  
      // Remove user inaccessible keywords.
      if (DAK.hasValue() && DeclAttribute::isUserInaccessible(*DAK))
        return;
  
      // Remove keywords only available when concurrency is enabled.
      if (DAK.hasValue() && !IsConcurrencyEnabled &&
          DeclAttribute::isConcurrencyOnly(*DAK))
        return;
  
      // Remove keywords only available when distributed is enabled.
      if (DAK.hasValue() && !IsDistributedEnabled &&
          DeclAttribute::isDistributedOnly(*DAK))
        return;
  
      addKeyword(
          Sink, Name, Kind, /*TypeAnnotation=*/"",
          /*TypeRelation=*/CodeCompletionResult::ExpectedTypeRelation::NotApplicable,
          getFlair(Kind, DAK));
    };
  
  #define DECL_KEYWORD(kw)                                                       \
    AddDeclKeyword(#kw, CodeCompletionKeywordKind::kw_##kw, None);
  #include "swift/Syntax/TokenKinds.def"
  
    // Context-sensitive keywords.
    auto AddCSKeyword = [&](StringRef Name, DeclAttrKind Kind) {
      AddDeclKeyword(Name, CodeCompletionKeywordKind::None, Kind);
    };
  
  #define CONTEXTUAL_CASE(KW, CLASS) AddCSKeyword(#KW, DAK_##CLASS);
  #define CONTEXTUAL_DECL_ATTR(KW, CLASS, ...) CONTEXTUAL_CASE(KW, CLASS)
  #define CONTEXTUAL_DECL_ATTR_ALIAS(KW, CLASS) CONTEXTUAL_CASE(KW, CLASS)
  #define CONTEXTUAL_SIMPLE_DECL_ATTR(KW, CLASS, ...) CONTEXTUAL_CASE(KW, CLASS)
  #include <swift/AST/Attr.def>
  #undef CONTEXTUAL_CASE
  }
  
  static void addStmtKeywords(CodeCompletionResultSink &Sink, DeclContext *DC,
                              bool MaybeFuncBody) {
    CodeCompletionFlair flair;
    // Starting a statement at top-level in non-script files is invalid.
    if (isCodeCompletionAtTopLevelOfLibraryFile(DC)) {
      flair |= CodeCompletionFlairBit::ExpressionAtNonScriptOrMainFileScope;
    }
  
    auto AddStmtKeyword = [&](StringRef Name, CodeCompletionKeywordKind Kind) {
      if (!MaybeFuncBody && Kind == CodeCompletionKeywordKind::kw_return)
        return;
      addKeyword(Sink, Name, Kind, "",
                 CodeCompletionResult::ExpectedTypeRelation::NotApplicable,
                 flair);
    };
  #define STMT_KEYWORD(kw) AddStmtKeyword(#kw, CodeCompletionKeywordKind::kw_##kw);
  #include "swift/Syntax/TokenKinds.def"
  }
  
  static void addCaseStmtKeywords(CodeCompletionResultSink &Sink) {
    addKeyword(Sink, "case", CodeCompletionKeywordKind::kw_case);
    addKeyword(Sink, "default", CodeCompletionKeywordKind::kw_default);
  }
  
  static void addLetVarKeywords(CodeCompletionResultSink &Sink) {
    addKeyword(Sink, "let", CodeCompletionKeywordKind::kw_let);
    addKeyword(Sink, "var", CodeCompletionKeywordKind::kw_var);
  }
  
  static void addAccessorKeywords(CodeCompletionResultSink &Sink) {
    addKeyword(Sink, "get", CodeCompletionKeywordKind::None);
    addKeyword(Sink, "set", CodeCompletionKeywordKind::None);
  }
  
  static void addObserverKeywords(CodeCompletionResultSink &Sink) {
    addKeyword(Sink, "willSet", CodeCompletionKeywordKind::None);
    addKeyword(Sink, "didSet", CodeCompletionKeywordKind::None);
  }
  
  static void addExprKeywords(CodeCompletionResultSink &Sink, DeclContext *DC) {
    // Expression is invalid at top-level of non-script files.
    CodeCompletionFlair flair;
    if (isCodeCompletionAtTopLevelOfLibraryFile(DC)) {
      flair |= CodeCompletionFlairBit::ExpressionAtNonScriptOrMainFileScope;
    }
  
    // Expr keywords.
    addKeyword(Sink, "try", CodeCompletionKeywordKind::kw_try, "",
               CodeCompletionResult::ExpectedTypeRelation::NotApplicable, flair);
    addKeyword(Sink, "try!", CodeCompletionKeywordKind::kw_try, "",
               CodeCompletionResult::ExpectedTypeRelation::NotApplicable, flair);
    addKeyword(Sink, "try?", CodeCompletionKeywordKind::kw_try, "",
               CodeCompletionResult::ExpectedTypeRelation::NotApplicable, flair);
    addKeyword(Sink, "await", CodeCompletionKeywordKind::None, "",
               CodeCompletionResult::ExpectedTypeRelation::NotApplicable, flair);
  }
  
  static void addOpaqueTypeKeyword(CodeCompletionResultSink &Sink) {
    addKeyword(Sink, "some", CodeCompletionKeywordKind::None, "some");
  }
  
  static void addAnyTypeKeyword(CodeCompletionResultSink &Sink, Type T) {
    CodeCompletionResultBuilder Builder(Sink,
                                        CodeCompletionResult::ResultKind::Keyword,
                                        SemanticContextKind::None, {});
    Builder.setKeywordKind(CodeCompletionKeywordKind::None);
    Builder.addKeyword("Any");
    Builder.addTypeAnnotation(T, PrintOptions());
  }
  
  void CodeCompletionCallbacksImpl::addKeywords(CodeCompletionResultSink &Sink,
                                                bool MaybeFuncBody) {
    switch (Kind) {
    case CompletionKind::None:
    case CompletionKind::DotExpr:
    case CompletionKind::AttributeDeclParen:
    case CompletionKind::AttributeBegin:
    case CompletionKind::PoundAvailablePlatform:
    case CompletionKind::Import:
    case CompletionKind::UnresolvedMember:
    case CompletionKind::LabeledTrailingClosure:
    case CompletionKind::AfterPoundExpr:
    case CompletionKind::AfterPoundDirective:
    case CompletionKind::PlatformConditon:
    case CompletionKind::GenericRequirement:
    case CompletionKind::KeyPathExprObjC:
    case CompletionKind::KeyPathExprSwift:
    case CompletionKind::PrecedenceGroup:
    case CompletionKind::StmtLabel:
    case CompletionKind::TypeAttrBeginning:
      break;
  
    case CompletionKind::EffectsSpecifier: {
      if (!llvm::is_contained(ParsedKeywords, "async"))
        addKeyword(Sink, "async", CodeCompletionKeywordKind::None);
      if (!llvm::is_contained(ParsedKeywords, "throws"))
        addKeyword(Sink, "throws", CodeCompletionKeywordKind::kw_throws);
      break;
    }
  
    case CompletionKind::AccessorBeginning: {
      // TODO: Omit already declared or mutally exclusive accessors.
      //       E.g. If 'get' is already declared, emit 'set' only.
      addAccessorKeywords(Sink);
  
      // Only 'var' for non-protocol context can have 'willSet' and 'didSet'.
      assert(ParsedDecl);
      VarDecl *var = dyn_cast<VarDecl>(ParsedDecl);
      if (auto accessor = dyn_cast<AccessorDecl>(ParsedDecl))
        var = dyn_cast<VarDecl>(accessor->getStorage());
      if (var && !var->getDeclContext()->getSelfProtocolDecl())
        addObserverKeywords(Sink);
  
      if (!isa<AccessorDecl>(ParsedDecl))
        break;
  
      MaybeFuncBody = true;
      LLVM_FALLTHROUGH;
    }
    case CompletionKind::StmtOrExpr:
      addDeclKeywords(Sink, CurDeclContext,
                      Context.LangOpts.EnableExperimentalConcurrency,
                      Context.LangOpts.EnableExperimentalDistributed);
      addStmtKeywords(Sink, CurDeclContext, MaybeFuncBody);
      LLVM_FALLTHROUGH;
    case CompletionKind::ReturnStmtExpr:
    case CompletionKind::YieldStmtExpr:
    case CompletionKind::PostfixExprBeginning:
    case CompletionKind::ForEachSequence:
      addSuperKeyword(Sink);
      addLetVarKeywords(Sink);
      addExprKeywords(Sink, CurDeclContext);
      addAnyTypeKeyword(Sink, CurDeclContext->getASTContext().TheAnyType);
      break;
  
    case CompletionKind::CallArg:
    case CompletionKind::PostfixExprParen:
      // Note that we don't add keywords here as the completion might be for
      // an argument list pattern. We instead add keywords later in
      // CodeCompletionCallbacksImpl::doneParsing when we know we're not
      // completing for a argument list pattern.
      break;
  
    case CompletionKind::CaseStmtKeyword:
      addCaseStmtKeywords(Sink);
      break;
  
    case CompletionKind::PostfixExpr:
    case CompletionKind::CaseStmtBeginning:
    case CompletionKind::TypeIdentifierWithDot:
    case CompletionKind::TypeIdentifierWithoutDot:
      break;
  
    case CompletionKind::TypeDeclResultBeginning: {
      auto DC = CurDeclContext;
      if (ParsedDecl && ParsedDecl == CurDeclContext->getAsDecl())
        DC = ParsedDecl->getDeclContext();
      if (!isa<ProtocolDecl>(DC))
        if (DC->isTypeContext() || isa_and_nonnull<FuncDecl>(ParsedDecl))
          addOpaqueTypeKeyword(Sink);
  
      LLVM_FALLTHROUGH;
    }
    case CompletionKind::TypeSimpleBeginning:
      addAnyTypeKeyword(Sink, CurDeclContext->getASTContext().TheAnyType);
      break;
  
    case CompletionKind::NominalMemberBeginning: {
      bool HasDeclIntroducer = llvm::find_if(ParsedKeywords,
                                             [this](const StringRef kw) {
        return llvm::StringSwitch<bool>(kw)
          .Case("associatedtype", true)
          .Case("class", !CurDeclContext || !isa<ClassDecl>(CurDeclContext))
          .Case("deinit", true)
          .Case("enum", true)
          .Case("extension", true)
          .Case("func", true)
          .Case("import", true)
          .Case("init", true)
          .Case("let", true)
          .Case("operator", true)
          .Case("precedencegroup", true)
          .Case("protocol", true)
          .Case("struct", true)
          .Case("subscript", true)
          .Case("typealias", true)
          .Case("var", true)
          .Default(false);
      }) != ParsedKeywords.end();
      if (!HasDeclIntroducer) {
        addDeclKeywords(Sink, CurDeclContext,
                        Context.LangOpts.EnableExperimentalConcurrency,
                        Context.LangOpts.EnableExperimentalDistributed);
        addLetVarKeywords(Sink);
      }
      break;
    }
  
    case CompletionKind::AfterIfStmtElse:
      addKeyword(Sink, "if", CodeCompletionKeywordKind::kw_if);
      break;
    case CompletionKind::ForEachPatternBeginning:
      if (!llvm::is_contained(ParsedKeywords, "try"))
        addKeyword(Sink, "try", CodeCompletionKeywordKind::kw_try);
      if (!llvm::is_contained(ParsedKeywords, "await"))
        addKeyword(Sink, "await", CodeCompletionKeywordKind::None);
      addKeyword(Sink, "var", CodeCompletionKeywordKind::kw_var);
      addKeyword(Sink, "case", CodeCompletionKeywordKind::kw_case);
    }
  }
  
  static void addPoundDirectives(CodeCompletionResultSink &Sink) {
    auto addWithName =
        [&](StringRef name, CodeCompletionKeywordKind K,
            llvm::function_ref<void(CodeCompletionResultBuilder &)> consumer =
                nullptr) {
          CodeCompletionResultBuilder Builder(Sink, CodeCompletionResult::Keyword,
                                              SemanticContextKind::None, {});
          Builder.addBaseName(name);
          Builder.setKeywordKind(K);
          if (consumer)
            consumer(Builder);
        };
  
    addWithName("sourceLocation", CodeCompletionKeywordKind::pound_sourceLocation,
                [&] (CodeCompletionResultBuilder &Builder) {
      Builder.addLeftParen();
      Builder.addTextChunk("file");
      Builder.addCallParameterColon();
      Builder.addSimpleTypedParameter("String");
      Builder.addComma();
      Builder.addTextChunk("line");
      Builder.addCallParameterColon();
      Builder.addSimpleTypedParameter("Int");
      Builder.addRightParen();
    });
    addWithName("warning", CodeCompletionKeywordKind::pound_warning,
                [&] (CodeCompletionResultBuilder &Builder) {
      Builder.addLeftParen();
      Builder.addTextChunk("\"");
      Builder.addSimpleNamedParameter("message");
      Builder.addTextChunk("\"");
      Builder.addRightParen();
    });
    addWithName("error", CodeCompletionKeywordKind::pound_error,
                [&] (CodeCompletionResultBuilder &Builder) {
      Builder.addLeftParen();
      Builder.addTextChunk("\"");
      Builder.addSimpleNamedParameter("message");
      Builder.addTextChunk("\"");
      Builder.addRightParen();
    });
  
    addWithName("if ", CodeCompletionKeywordKind::pound_if,
                [&] (CodeCompletionResultBuilder &Builder) {
      Builder.addSimpleNamedParameter("condition");
    });
  
    // FIXME: These directives are only valid in conditional completion block.
    addWithName("elseif ", CodeCompletionKeywordKind::pound_elseif,
                [&] (CodeCompletionResultBuilder &Builder) {
      Builder.addSimpleNamedParameter("condition");
    });
    addWithName("else", CodeCompletionKeywordKind::pound_else);
    addWithName("endif", CodeCompletionKeywordKind::pound_endif);
  }
  
  /// Add platform conditions used in '#if' and '#elseif' directives.
  static void addPlatformConditions(CodeCompletionResultSink &Sink) {
    auto addWithName =
        [&](StringRef Name,
            llvm::function_ref<void(CodeCompletionResultBuilder & Builder)>
                consumer) {
          CodeCompletionResultBuilder Builder(
              Sink, CodeCompletionResult::ResultKind::Pattern,
              // FIXME: SemanticContextKind::CurrentModule is not correct.
              // Use 'None' (and fix prioritization) or introduce a new context.
              SemanticContextKind::CurrentModule, {});
          Builder.addFlair(CodeCompletionFlairBit::ExpressionSpecific);
          Builder.addBaseName(Name);
          Builder.addLeftParen();
          consumer(Builder);
          Builder.addRightParen();
        };
  
    addWithName("os", [](CodeCompletionResultBuilder &Builder) {
      Builder.addSimpleNamedParameter("name");
    });
    addWithName("arch", [](CodeCompletionResultBuilder &Builder) {
      Builder.addSimpleNamedParameter("name");
    });
    addWithName("canImport", [](CodeCompletionResultBuilder &Builder) {
      Builder.addSimpleNamedParameter("module");
    });
    addWithName("targetEnvironment", [](CodeCompletionResultBuilder &Builder) {
      Builder.addTextChunk("simulator");
    });
    addWithName("swift", [](CodeCompletionResultBuilder &Builder) {
      Builder.addTextChunk(">=");
      Builder.addSimpleNamedParameter("version");
    });
    addWithName("swift", [](CodeCompletionResultBuilder &Builder) {
      Builder.addTextChunk("<");
      Builder.addSimpleNamedParameter("version");
    });
    addWithName("compiler", [](CodeCompletionResultBuilder &Builder) {
      Builder.addTextChunk(">=");
      Builder.addSimpleNamedParameter("version");
    });
    addWithName("compiler", [](CodeCompletionResultBuilder &Builder) {
      Builder.addTextChunk("<");
      Builder.addSimpleNamedParameter("version");
    });
  
    addKeyword(Sink, "true", CodeCompletionKeywordKind::kw_true, "Bool");
    addKeyword(Sink, "false", CodeCompletionKeywordKind::kw_false, "Bool");
  }
  
  /// Add flags specified by '-D' to completion results.
  static void addConditionalCompilationFlags(ASTContext &Ctx,
                                             CodeCompletionResultSink &Sink) {
    for (auto Flag : Ctx.LangOpts.getCustomConditionalCompilationFlags()) {
      // TODO: Should we filter out some flags?
      CodeCompletionResultBuilder Builder(
          Sink, CodeCompletionResult::ResultKind::Keyword,
          // FIXME: SemanticContextKind::CurrentModule is not correct.
          // Use 'None' (and fix prioritization) or introduce a new context.
          SemanticContextKind::CurrentModule, {});
      Builder.addFlair(CodeCompletionFlairBit::ExpressionSpecific);
      Builder.addTextChunk(Flag);
    }
  }
  
  /// Add flairs to the each item in \p results .
  ///
  /// If \p Sink is passed, the pointer of the each result may be replaced with a
  /// pointer to the new item allocated in \p Sink.
  /// If \p Sink is nullptr, the pointee of each result may be modified in place.
  static void postProcessResults(MutableArrayRef<CodeCompletionResult *> results,
                                 CompletionKind Kind, DeclContext *DC,
                                 CodeCompletionResultSink *Sink) {
    for (CodeCompletionResult *&result : results) {
      bool modified = false;
      auto flair = result->getFlair();
  
      // Starting a statement with a protocol name is not common. So protocol
      // names at non-type name position are "rare".
      if (result->getKind() == CodeCompletionResult::ResultKind::Declaration &&
          result->getAssociatedDeclKind() == CodeCompletionDeclKind::Protocol &&
          Kind != CompletionKind::TypeSimpleBeginning &&
          Kind != CompletionKind::TypeIdentifierWithoutDot &&
          Kind != CompletionKind::TypeIdentifierWithDot &&
          Kind != CompletionKind::TypeDeclResultBeginning &&
          Kind != CompletionKind::GenericRequirement) {
        flair |= CodeCompletionFlairBit::RareTypeAtCurrentPosition;
        modified = true;
      }
  
      // Starting a statement at top-level in non-script files is invalid.
      if (Kind == CompletionKind::StmtOrExpr &&
          result->getKind() == CodeCompletionResult::ResultKind::Declaration &&
          isCodeCompletionAtTopLevelOfLibraryFile(DC)) {
        flair |= CodeCompletionFlairBit::ExpressionAtNonScriptOrMainFileScope;
        modified = true;
      }
  
      if (!modified)
        continue;
  
      if (Sink) {
        // Replace the result with a new result with the flair.
        result = result->withFlair(flair, *Sink);
      } else {
        // 'Sink' == nullptr means the result is modifiable in place.
        result->setFlair(flair);
      }
    }
  }
  
  static void deliverCompletionResults(CodeCompletionContext &CompletionContext,
                                       CompletionLookup &Lookup,
                                       DeclContext *DC,
                                       CodeCompletionConsumer &Consumer) {
    auto &SF = *DC->getParentSourceFile();
    llvm::SmallPtrSet<Identifier, 8> seenModuleNames;
    std::vector<RequestedCachedModule> RequestedModules;
  
    SmallPtrSet<ModuleDecl *, 4> explictlyImportedModules;
    {
      // Collect modules directly imported in this SourceFile.
      SmallVector<ImportedModule, 4> directImport;
      SF.getImportedModules(directImport,
                            {ModuleDecl::ImportFilterKind::Default,
                             ModuleDecl::ImportFilterKind::ImplementationOnly});
      for (auto import : directImport)
        explictlyImportedModules.insert(import.importedModule);
  
      // Exclude modules implicitly imported in the current module.
      auto implicitImports = SF.getParentModule()->getImplicitImports();
      for (auto import : implicitImports.imports)
        explictlyImportedModules.erase(import.module.importedModule);
  
      // Consider the current module "explicit".
      explictlyImportedModules.insert(SF.getParentModule());
    }
  
    for (auto &Request: Lookup.RequestedCachedResults) {
      llvm::DenseSet<CodeCompletionCache::Key> ImportsSeen;
      auto handleImport = [&](ImportedModule Import) {
        ModuleDecl *TheModule = Import.importedModule;
        ImportPath::Access Path = Import.accessPath;
        if (TheModule->getFiles().empty())
          return;
  
        // Clang submodules are ignored and there's no lookup cost involved,
        // so just ignore them and don't put the empty results in the cache
        // because putting a lot of objects in the cache will push out
        // other lookups.
        if (isClangSubModule(TheModule))
          return;
  
        std::vector<std::string> AccessPath;
        for (auto Piece : Path) {
          AccessPath.push_back(std::string(Piece.Item));
        }
  
        StringRef ModuleFilename = TheModule->getModuleFilename();
        // ModuleFilename can be empty if something strange happened during
        // module loading, for example, the module file is corrupted.
        if (!ModuleFilename.empty()) {
          CodeCompletionCache::Key K{
              ModuleFilename.str(),
              std::string(TheModule->getName()),
              AccessPath,
              Request.NeedLeadingDot,
              SF.hasTestableOrPrivateImport(
                  AccessLevel::Internal, TheModule,
                  SourceFile::ImportQueryKind::TestableOnly),
              SF.hasTestableOrPrivateImport(
                  AccessLevel::Internal, TheModule,
                  SourceFile::ImportQueryKind::PrivateOnly),
              CompletionContext.getAddInitsToTopLevel(),
              CompletionContext.getAnnotateResult(),
          };
  
          using PairType = llvm::DenseSet<swift::ide::CodeCompletionCache::Key,
              llvm::DenseMapInfo<CodeCompletionCache::Key>>::iterator;
          std::pair<PairType, bool> Result = ImportsSeen.insert(K);
          if (!Result.second)
            return; // already handled.
          RequestedModules.push_back({std::move(K), TheModule,
            Request.OnlyTypes, Request.OnlyPrecedenceGroups});
  
          auto TheModuleName = TheModule->getName();
          if (Request.IncludeModuleQualifier &&
              (!Lookup.isHiddenModuleName(TheModuleName) ||
               explictlyImportedModules.contains(TheModule)) &&
              seenModuleNames.insert(TheModuleName).second)
            Lookup.addModuleName(TheModule);
        }
      };
  
      if (Request.TheModule) {
        // FIXME: actually check imports.
        for (auto Import : namelookup::getAllImports(Request.TheModule)) {
          handleImport(Import);
        }
      } else {
        // Add results from current module.
        Lookup.getToplevelCompletions(Request.OnlyTypes);
  
        // Add the qualifying module name
        auto curModule = SF.getParentModule();
        if (Request.IncludeModuleQualifier &&
            seenModuleNames.insert(curModule->getName()).second)
          Lookup.addModuleName(curModule);
  
        // Add results for all imported modules.
        SmallVector<ImportedModule, 4> Imports;
        SF.getImportedModules(
            Imports, {ModuleDecl::ImportFilterKind::Exported,
                      ModuleDecl::ImportFilterKind::Default,
                      ModuleDecl::ImportFilterKind::ImplementationOnly});
  
        for (auto Imported : Imports) {
          for (auto Import : namelookup::getAllImports(Imported.importedModule))
            handleImport(Import);
        }
      }
    }
    Lookup.RequestedCachedResults.clear();
    CompletionContext.typeContextKind = Lookup.typeContextKind();
  
    postProcessResults(CompletionContext.getResultSink().Results,
                       CompletionContext.CodeCompletionKind, DC,
                       /*Sink=*/nullptr);
  
    Consumer.handleResultsAndModules(CompletionContext, RequestedModules, DC);
  }
  
  void deliverUnresolvedMemberResults(
      ArrayRef<UnresolvedMemberTypeCheckCompletionCallback::ExprResult> Results,
      ArrayRef<Type> EnumPatternTypes, DeclContext *DC, SourceLoc DotLoc,
      ide::CodeCompletionContext &CompletionCtx,
      CodeCompletionConsumer &Consumer) {
    ASTContext &Ctx = DC->getASTContext();
    CompletionLookup Lookup(CompletionCtx.getResultSink(), Ctx, DC,
                            &CompletionCtx);
  
    assert(DotLoc.isValid());
    Lookup.setHaveDot(DotLoc);
    Lookup.shouldCheckForDuplicates(Results.size() + EnumPatternTypes.size() > 1);
  
    // Get the canonical versions of the top-level types
    SmallPtrSet<CanType, 4> originalTypes;
    for (auto &Result: Results)
      originalTypes.insert(Result.ExpectedTy->getCanonicalType());
  
    for (auto &Result: Results) {
      Lookup.setExpectedTypes({Result.ExpectedTy},
                              Result.IsImplicitSingleExpressionReturn,
                              /*expectsNonVoid*/true);
      Lookup.setIdealExpectedType(Result.ExpectedTy);
  
      // For optional types, also get members of the unwrapped type if it's not
      // already equivalent to one of the top-level types. Handling it via the top
      // level type and not here ensures we give the correct type relation
      // (identical, rather than convertible).
      if (Result.ExpectedTy->getOptionalObjectType()) {
        Type Unwrapped = Result.ExpectedTy->lookThroughAllOptionalTypes();
        if (originalTypes.insert(Unwrapped->getCanonicalType()).second)
          Lookup.getUnresolvedMemberCompletions(Unwrapped);
      }
      Lookup.getUnresolvedMemberCompletions(Result.ExpectedTy);
    }
  
    // Offer completions when interpreting the pattern match as an
    // EnumElementPattern.
    for (auto &Ty : EnumPatternTypes) {
      Lookup.setExpectedTypes({Ty}, /*IsImplicitSingleExpressionReturn=*/false,
                              /*expectsNonVoid=*/true);
      Lookup.setIdealExpectedType(Ty);
  
      // We can pattern match MyEnum against Optional<MyEnum>
      if (Ty->getOptionalObjectType()) {
        Type Unwrapped = Ty->lookThroughAllOptionalTypes();
        Lookup.getEnumElementPatternCompletions(Unwrapped);
      }
  
      Lookup.getEnumElementPatternCompletions(Ty);
    }
  
    deliverCompletionResults(CompletionCtx, Lookup, DC, Consumer);
  }
  
  void deliverKeyPathResults(
      ArrayRef<KeyPathTypeCheckCompletionCallback::Result> Results,
      DeclContext *DC, SourceLoc DotLoc,
      ide::CodeCompletionContext &CompletionCtx,
      CodeCompletionConsumer &Consumer) {
    ASTContext &Ctx = DC->getASTContext();
    CompletionLookup Lookup(CompletionCtx.getResultSink(), Ctx, DC,
                            &CompletionCtx);
  
    if (DotLoc.isValid()) {
      Lookup.setHaveDot(DotLoc);
    }
    Lookup.shouldCheckForDuplicates(Results.size() > 1);
  
    for (auto &Result : Results) {
      Lookup.setIsSwiftKeyPathExpr(Result.OnRoot);
      Lookup.getValueExprCompletions(Result.BaseType);
    }
  
    deliverCompletionResults(CompletionCtx, Lookup, DC, Consumer);
  }
  
  void deliverDotExprResults(
      ArrayRef<DotExprTypeCheckCompletionCallback::Result> Results,
      Expr *BaseExpr, DeclContext *DC, SourceLoc DotLoc, bool IsInSelector,
      ide::CodeCompletionContext &CompletionCtx,
      CodeCompletionConsumer &Consumer) {
    ASTContext &Ctx = DC->getASTContext();
    CompletionLookup Lookup(CompletionCtx.getResultSink(), Ctx, DC,
                            &CompletionCtx);
  
    if (DotLoc.isValid())
      Lookup.setHaveDot(DotLoc);
  
    Lookup.setIsSuperRefExpr(isa<SuperRefExpr>(BaseExpr));
  
    if (auto *DRE = dyn_cast<DeclRefExpr>(BaseExpr))
      Lookup.setIsSelfRefExpr(DRE->getDecl()->getName() == Ctx.Id_self);
  
    if (isa<BindOptionalExpr>(BaseExpr) || isa<ForceValueExpr>(BaseExpr))
      Lookup.setIsUnwrappedOptional(true);
  
    if (IsInSelector) {
      Lookup.includeInstanceMembers();
      Lookup.setPreferFunctionReferencesToCalls();
    }
  
    Lookup.shouldCheckForDuplicates(Results.size() > 1);
    for (auto &Result: Results) {
      Lookup.setIsStaticMetatype(Result.BaseIsStaticMetaType);
      Lookup.getPostfixKeywordCompletions(Result.BaseTy, BaseExpr);
      Lookup.setExpectedTypes(Result.ExpectedTypes,
                              Result.IsImplicitSingleExpressionReturn,
                              Result.ExpectsNonVoid);
      if (isDynamicLookup(Result.BaseTy))
        Lookup.setIsDynamicLookup();
      Lookup.getValueExprCompletions(Result.BaseTy, Result.BaseDecl);
    }
  
    deliverCompletionResults(CompletionCtx, Lookup, DC, Consumer);
  }
  
  bool CodeCompletionCallbacksImpl::trySolverCompletion(bool MaybeFuncBody) {
    assert(ParsedExpr || CurDeclContext);
  
    SourceLoc CompletionLoc = ParsedExpr
      ? ParsedExpr->getLoc()
      : CurDeclContext->getASTContext().SourceMgr.getCodeCompletionLoc();
  
    switch (Kind) {
    case CompletionKind::DotExpr: {
      assert(CodeCompleteTokenExpr);
      assert(CurDeclContext);
  
      DotExprTypeCheckCompletionCallback Lookup(CurDeclContext,
                                                CodeCompleteTokenExpr);
      llvm::SaveAndRestore<TypeCheckCompletionCallback*>
        CompletionCollector(Context.CompletionCallback, &Lookup);
      typeCheckContextAt(CurDeclContext, CompletionLoc);
  
      // This (hopefully) only happens in cases where the expression isn't
      // typechecked during normal compilation either (e.g. member completion in a
      // switch case where there control expression is invalid). Having normal
      // typechecking still resolve even these cases would be beneficial for
      // tooling in general though.
      if (!Lookup.gotCallback())
        Lookup.fallbackTypeCheck();
  
      addKeywords(CompletionContext.getResultSink(), MaybeFuncBody);
  
      Expr *CheckedBase = CodeCompleteTokenExpr->getBase();
      deliverDotExprResults(Lookup.getResults(), CheckedBase, CurDeclContext,
                            DotLoc, isInsideObjCSelector(), CompletionContext,
                            Consumer);
      return true;
    }
    case CompletionKind::UnresolvedMember: {
      assert(CodeCompleteTokenExpr);
      assert(CurDeclContext);
  
      UnresolvedMemberTypeCheckCompletionCallback Lookup(CodeCompleteTokenExpr);
      llvm::SaveAndRestore<TypeCheckCompletionCallback*>
        CompletionCollector(Context.CompletionCallback, &Lookup);
      typeCheckContextAt(CurDeclContext, CompletionLoc);
  
      if (!Lookup.gotCallback())
        Lookup.fallbackTypeCheck(CurDeclContext);
  
      addKeywords(CompletionContext.getResultSink(), MaybeFuncBody);
      deliverUnresolvedMemberResults(Lookup.getExprResults(),
                                     Lookup.getEnumPatternTypes(), CurDeclContext,
                                     DotLoc, CompletionContext, Consumer);
      return true;
    }
    case CompletionKind::KeyPathExprSwift: {
      assert(CurDeclContext);
  
      // CodeCompletionCallbacks::completeExprKeyPath takes a \c KeyPathExpr,
      // so we can safely cast the \c ParsedExpr back to a \c KeyPathExpr.
      auto KeyPath = cast<KeyPathExpr>(ParsedExpr);
      KeyPathTypeCheckCompletionCallback Lookup(KeyPath);
      llvm::SaveAndRestore<TypeCheckCompletionCallback *> CompletionCollector(
          Context.CompletionCallback, &Lookup);
      typeCheckContextAt(CurDeclContext, CompletionLoc);
  
      deliverKeyPathResults(Lookup.getResults(), CurDeclContext, DotLoc,
                            CompletionContext, Consumer);
      return true;
    }
    default:
      return false;
    }
  }
  
  // Undoes the single-expression closure/function body transformation on the
  // given DeclContext and its parent contexts if they have a single expression
  // body that contains the code completion location.
  //
  // FIXME: Remove this once all expression position completions are migrated
  // to work via TypeCheckCompletionCallback.
  static void undoSingleExpressionReturn(DeclContext *DC) {
    auto updateBody = [](BraceStmt *BS, ASTContext &Ctx) -> bool {
      ASTNode LastElem = BS->getLastElement();
      auto *RS = dyn_cast_or_null<ReturnStmt>(LastElem.dyn_cast<Stmt*>());
  
      if (!RS || !RS->isImplicit())
        return false;
  
      BS->setLastElement(RS->getResult());
      return true;
    };
  
    while (ClosureExpr *CE = dyn_cast_or_null<ClosureExpr>(DC)) {
      if (CE->hasSingleExpressionBody()) {
        if (updateBody(CE->getBody(), CE->getASTContext()))
          CE->setBody(CE->getBody(), false);
      }
      DC = DC->getParent();
    }
    if (FuncDecl *FD = dyn_cast_or_null<FuncDecl>(DC)) {
      if (FD->hasSingleExpressionBody()) {
        if (updateBody(FD->getBody(), FD->getASTContext()))
          FD->setHasSingleExpressionBody(false);
      }
    }
  }
  
  void CodeCompletionCallbacksImpl::doneParsing() {
    CompletionContext.CodeCompletionKind = Kind;
  
    if (Kind == CompletionKind::None) {
      return;
    }
  
    bool MaybeFuncBody = true;
    if (CurDeclContext) {
      auto *CD = CurDeclContext->getLocalContext();
      if (!CD || CD->getContextKind() == DeclContextKind::Initializer ||
          CD->getContextKind() == DeclContextKind::TopLevelCodeDecl)
        MaybeFuncBody = false;
    }
  
    if (auto *DC = dyn_cast_or_null<DeclContext>(ParsedDecl)) {
      if (DC->isChildContextOf(CurDeclContext))
        CurDeclContext = DC;
    }
  
    if (trySolverCompletion(MaybeFuncBody))
      return;
  
    undoSingleExpressionReturn(CurDeclContext);
    typeCheckContextAt(
        CurDeclContext,
        ParsedExpr
            ? ParsedExpr->getLoc()
            : CurDeclContext->getASTContext().SourceMgr.getCodeCompletionLoc());
  
    // Add keywords even if type checking fails completely.
    addKeywords(CompletionContext.getResultSink(), MaybeFuncBody);
  
    Optional<Type> ExprType;
    ConcreteDeclRef ReferencedDecl = nullptr;
    if (ParsedExpr) {
      if (auto *checkedExpr = findParsedExpr(CurDeclContext,
                                             ParsedExpr->getSourceRange())) {
        ParsedExpr = checkedExpr;
      }
  
      if (auto typechecked = typeCheckParsedExpr()) {
        ExprType = typechecked->first;
        ReferencedDecl = typechecked->second;
        ParsedExpr->setType(*ExprType);
      }
  
      if (!ExprType && Kind != CompletionKind::PostfixExprParen &&
          Kind != CompletionKind::CallArg &&
          Kind != CompletionKind::KeyPathExprObjC)
        return;
    }
  
    if (!ParsedTypeLoc.isNull() && !typecheckParsedType())
      return;
  
    CompletionLookup Lookup(CompletionContext.getResultSink(), P.Context,
                            CurDeclContext, &CompletionContext);
    if (ExprType) {
      Lookup.setIsStaticMetatype(ParsedExpr->isStaticallyDerivedMetatype());
    }
    if (auto *DRE = dyn_cast_or_null<DeclRefExpr>(ParsedExpr)) {
      Lookup.setIsSelfRefExpr(DRE->getDecl()->getName() == Context.Id_self);
    } else if (isa_and_nonnull<SuperRefExpr>(ParsedExpr)) {
      Lookup.setIsSuperRefExpr();
    }
  
    if (isInsideObjCSelector())
      Lookup.includeInstanceMembers();
    if (PreferFunctionReferencesToCalls)
      Lookup.setPreferFunctionReferencesToCalls();
  
    auto DoPostfixExprBeginning = [&] (){
      SourceLoc Loc = P.Context.SourceMgr.getCodeCompletionLoc();
      Lookup.getValueCompletionsInDeclContext(Loc);
      Lookup.getSelfTypeCompletionInDeclContext(Loc, /*isForDeclResult=*/false);
    };
  
    switch (Kind) {
    case CompletionKind::None:
    case CompletionKind::DotExpr:
    case CompletionKind::UnresolvedMember:
    case CompletionKind::KeyPathExprSwift:
      llvm_unreachable("should be already handled");
      return;
  
    case CompletionKind::StmtOrExpr:
    case CompletionKind::ForEachSequence:
    case CompletionKind::PostfixExprBeginning: {
      ExprContextInfo ContextInfo(CurDeclContext, CodeCompleteTokenExpr);
      Lookup.setExpectedTypes(ContextInfo.getPossibleTypes(),
                              ContextInfo.isImplicitSingleExpressionReturn());
      DoPostfixExprBeginning();
      break;
    }
  
    case CompletionKind::PostfixExpr: {
      Lookup.setHaveLeadingSpace(HasSpace);
      if (isDynamicLookup(*ExprType))
        Lookup.setIsDynamicLookup();
      Lookup.getValueExprCompletions(*ExprType, ReferencedDecl.getDecl());
      /// We set the type of ParsedExpr explicitly above. But we don't want an
      /// unresolved type in our AST when we type check again for operator
      /// completions. Remove the type of the ParsedExpr and see if we can come up
      /// with something more useful based on the the full sequence expression.
      if (ParsedExpr->getType()->is<UnresolvedType>()) {
        ParsedExpr->setType(nullptr);
      }
      Lookup.getOperatorCompletions(ParsedExpr, leadingSequenceExprs);
      Lookup.getPostfixKeywordCompletions(*ExprType, ParsedExpr);
      break;
    }
  
    case CompletionKind::PostfixExprParen: {
      Lookup.setHaveLParen(true);
  
      ExprContextInfo ContextInfo(CurDeclContext, CodeCompleteTokenExpr);
  
      if (ShouldCompleteCallPatternAfterParen) {
        ExprContextInfo ParentContextInfo(CurDeclContext, ParsedExpr);
        Lookup.setExpectedTypes(
            ParentContextInfo.getPossibleTypes(),
            ParentContextInfo.isImplicitSingleExpressionReturn());
        if (!ContextInfo.getPossibleCallees().empty()) {
          for (auto &typeAndDecl : ContextInfo.getPossibleCallees())
            Lookup.tryFunctionCallCompletions(typeAndDecl.Type, typeAndDecl.Decl,
                                              typeAndDecl.SemanticContext);
        } else if (ExprType && ((*ExprType)->is<AnyFunctionType>() ||
                                (*ExprType)->is<AnyMetatypeType>())) {
          Lookup.getValueExprCompletions(*ExprType, ReferencedDecl.getDecl());
        }
      } else {
        // Add argument labels, then fallthrough to get values.
        Lookup.addCallArgumentCompletionResults(ContextInfo.getPossibleParams());
      }
  
      if (!Lookup.FoundFunctionCalls ||
          (Lookup.FoundFunctionCalls &&
           Lookup.FoundFunctionsWithoutFirstKeyword)) {
        Lookup.setExpectedTypes(ContextInfo.getPossibleTypes(),
                                ContextInfo.isImplicitSingleExpressionReturn());
        Lookup.setHaveLParen(false);
  
        // Add any keywords that can be used in an argument expr position.
        addSuperKeyword(CompletionContext.getResultSink());
        addExprKeywords(CompletionContext.getResultSink(), CurDeclContext);
  
        DoPostfixExprBeginning();
      }
      break;
    }
  
    case CompletionKind::KeyPathExprObjC: {
      if (DotLoc.isValid())
        Lookup.setHaveDot(DotLoc);
      Lookup.setIsKeyPathExpr();
      Lookup.includeInstanceMembers();
  
      if (ExprType) {
        if (isDynamicLookup(*ExprType))
          Lookup.setIsDynamicLookup();
  
        Lookup.getValueExprCompletions(*ExprType, ReferencedDecl.getDecl());
      } else {
        SourceLoc Loc = P.Context.SourceMgr.getCodeCompletionLoc();
        Lookup.getValueCompletionsInDeclContext(Loc, KeyPathFilter,
                                                /*LiteralCompletions=*/false);
      }
      break;
    }
  
    case CompletionKind::TypeDeclResultBeginning:
    case CompletionKind::TypeSimpleBeginning: {
      auto Loc = Context.SourceMgr.getCodeCompletionLoc();
      Lookup.getTypeCompletionsInDeclContext(Loc);
      Lookup.getSelfTypeCompletionInDeclContext(
          Loc, Kind == CompletionKind::TypeDeclResultBeginning);
      break;
    }
  
    case CompletionKind::TypeIdentifierWithDot: {
      Lookup.setHaveDot(SourceLoc());
      Lookup.getTypeCompletions(ParsedTypeLoc.getType());
      break;
    }
  
    case CompletionKind::TypeIdentifierWithoutDot: {
      Lookup.getTypeCompletions(ParsedTypeLoc.getType());
      break;
    }
  
    case CompletionKind::CaseStmtBeginning: {
      ExprContextInfo ContextInfo(CurDeclContext, CodeCompleteTokenExpr);
      Lookup.setExpectedTypes(ContextInfo.getPossibleTypes(),
                              ContextInfo.isImplicitSingleExpressionReturn());
      Lookup.setIdealExpectedType(CodeCompleteTokenExpr->getType());
      Lookup.getUnresolvedMemberCompletions(ContextInfo.getPossibleTypes());
      DoPostfixExprBeginning();
      break;
    }
  
    case CompletionKind::NominalMemberBeginning: {
      CompletionOverrideLookup OverrideLookup(CompletionContext.getResultSink(),
                                              P.Context, CurDeclContext,
                                              ParsedKeywords, introducerLoc);
      OverrideLookup.getOverrideCompletions(SourceLoc());
      break;
    }
  
    case CompletionKind::AccessorBeginning: {
      if (isa<AccessorDecl>(ParsedDecl)) {
        ExprContextInfo ContextInfo(CurDeclContext, CodeCompleteTokenExpr);
        Lookup.setExpectedTypes(ContextInfo.getPossibleTypes(),
                                ContextInfo.isImplicitSingleExpressionReturn());
        DoPostfixExprBeginning();
      }
      break;
    }
  
    case CompletionKind::AttributeBegin: {
      Lookup.getAttributeDeclCompletions(IsInSil, AttTargetDK);
  
      // TypeName at attribute position after '@'.
      // - VarDecl: Property Wrappers.
      // - ParamDecl/VarDecl/FuncDecl: Function Builders.
      if (!AttTargetDK || *AttTargetDK == DeclKind::Var ||
          *AttTargetDK == DeclKind::Param || *AttTargetDK == DeclKind::Func)
        Lookup.getTypeCompletionsInDeclContext(
            P.Context.SourceMgr.getCodeCompletionLoc());
      break;
    }
    case CompletionKind::AttributeDeclParen: {
      Lookup.getAttributeDeclParamCompletions(AttrKind, AttrParamIndex);
      break;
    }
    case CompletionKind::PoundAvailablePlatform: {
      Lookup.getPoundAvailablePlatformCompletions();
      break;
    }
    case CompletionKind::Import: {
      if (DotLoc.isValid())
        Lookup.addSubModuleNames(SubModuleNameVisibilityPairs);
      else
        Lookup.addImportModuleNames();
      break;
    }
    case CompletionKind::CallArg: {
      ExprContextInfo ContextInfo(CurDeclContext, CodeCompleteTokenExpr);
  
      bool shouldPerformGlobalCompletion = true;
  
      if (ShouldCompleteCallPatternAfterParen &&
          !ContextInfo.getPossibleCallees().empty()) {
        Lookup.setHaveLParen(true);
        for (auto &typeAndDecl : ContextInfo.getPossibleCallees()) {
          auto apply = ContextInfo.getAnalyzedExpr();
          if (isa_and_nonnull<SubscriptExpr>(apply)) {
            Lookup.addSubscriptCallPattern(
                typeAndDecl.Type,
                dyn_cast_or_null<SubscriptDecl>(typeAndDecl.Decl),
                typeAndDecl.SemanticContext);
          } else {
            Lookup.addFunctionCallPattern(
                typeAndDecl.Type,
                dyn_cast_or_null<AbstractFunctionDecl>(typeAndDecl.Decl),
                typeAndDecl.SemanticContext);
          }
        }
        Lookup.setHaveLParen(false);
  
        shouldPerformGlobalCompletion =
            !Lookup.FoundFunctionCalls ||
            (Lookup.FoundFunctionCalls &&
             Lookup.FoundFunctionsWithoutFirstKeyword);
      } else if (!ContextInfo.getPossibleParams().empty()) {
        auto params = ContextInfo.getPossibleParams();
        Lookup.addCallArgumentCompletionResults(params);
  
        shouldPerformGlobalCompletion = !ContextInfo.getPossibleTypes().empty();
        // Fallback to global completion if the position is out of number. It's
        // better than suggest nothing.
        shouldPerformGlobalCompletion |= llvm::all_of(
            params, [](const PossibleParamInfo &P) { return !P.Param; });
      }
  
      if (shouldPerformGlobalCompletion) {
        Lookup.setExpectedTypes(ContextInfo.getPossibleTypes(),
                                ContextInfo.isImplicitSingleExpressionReturn());
  
        // Add any keywords that can be used in an argument expr position.
        addSuperKeyword(CompletionContext.getResultSink());
        addExprKeywords(CompletionContext.getResultSink(), CurDeclContext);
  
        DoPostfixExprBeginning();
      }
      break;
    }
  
    case CompletionKind::LabeledTrailingClosure: {
      ExprContextInfo ContextInfo(CurDeclContext, CodeCompleteTokenExpr);
  
      SmallVector<PossibleParamInfo, 2> params;
      // Only complete function type parameters
      llvm::copy_if(ContextInfo.getPossibleParams(), std::back_inserter(params),
                    [](const PossibleParamInfo &P) {
                      // nullptr indicates out of bounds.
                      if (!P.Param)
                        return true;
                      return P.Param->getPlainType()
                          ->lookThroughAllOptionalTypes()
                          ->is<AnyFunctionType>();
                    });
  
      bool allRequired = false;
      if (!params.empty()) {
        Lookup.addCallArgumentCompletionResults(
            params, /*isLabeledTrailingClosure=*/true);
        allRequired = llvm::all_of(
            params, [](const PossibleParamInfo &P) { return P.IsRequired; });
      }
  
      // If there're optional parameters, do global completion or member
      // completion depending on the completion is happening at the start of line.
      if (!allRequired) {
        if (IsAtStartOfLine) {
          //   foo() {}
          //   <HERE>
  
          auto &Sink = CompletionContext.getResultSink();
          if (isa<Initializer>(CurDeclContext))
            CurDeclContext = CurDeclContext->getParent();
  
          if (CurDeclContext->isTypeContext()) {
            // Override completion (CompletionKind::NominalMemberBeginning).
            addDeclKeywords(Sink, CurDeclContext,
                            Context.LangOpts.EnableExperimentalConcurrency,
                            Context.LangOpts.EnableExperimentalDistributed);
            addLetVarKeywords(Sink);
            SmallVector<StringRef, 0> ParsedKeywords;
            CompletionOverrideLookup OverrideLookup(Sink, Context, CurDeclContext,
                                                    ParsedKeywords, SourceLoc());
            OverrideLookup.getOverrideCompletions(SourceLoc());
          } else {
            // Global completion (CompletionKind::PostfixExprBeginning).
            addDeclKeywords(Sink, CurDeclContext,
                            Context.LangOpts.EnableExperimentalConcurrency,
                            Context.LangOpts.EnableExperimentalDistributed);
            addStmtKeywords(Sink, CurDeclContext, MaybeFuncBody);
            addSuperKeyword(Sink);
            addLetVarKeywords(Sink);
            addExprKeywords(Sink, CurDeclContext);
            addAnyTypeKeyword(Sink, Context.TheAnyType);
            DoPostfixExprBeginning();
          }
        } else {
          //   foo() {} <HERE>
          // Member completion.
          Expr *analyzedExpr = ContextInfo.getAnalyzedExpr();
          if (!analyzedExpr)
            break;
  
          // Only if the completion token is the last token in the call.
          if (analyzedExpr->getEndLoc() != CodeCompleteTokenExpr->getLoc())
            break;
  
          Type resultTy = analyzedExpr->getType();
          // If the call expression doesn't have a type, fallback to:
          if (!resultTy || resultTy->is<ErrorType>()) {
            // 1) Try to type check removing CodeCompletionExpr from the call.
            Expr *removedExpr = analyzedExpr;
            removeCodeCompletionExpr(CurDeclContext->getASTContext(),
                                     removedExpr);
            ConcreteDeclRef referencedDecl;
            auto optT = getTypeOfCompletionContextExpr(
                CurDeclContext->getASTContext(), CurDeclContext,
                CompletionTypeCheckKind::Normal, removedExpr, referencedDecl);
            if (optT) {
              resultTy = *optT;
              analyzedExpr->setType(resultTy);
            }
          }
          if (!resultTy || resultTy->is<ErrorType>()) {
            // 2) Infer it from the possible callee info.
            if (!ContextInfo.getPossibleCallees().empty()) {
              auto calleeInfo = ContextInfo.getPossibleCallees()[0];
              resultTy = calleeInfo.Type->getResult();
              analyzedExpr->setType(resultTy);
            }
          }
          if (!resultTy || resultTy->is<ErrorType>()) {
            // 3) Give up providing postfix completions.
            break;
          }
  
          auto &SM = CurDeclContext->getASTContext().SourceMgr;
          auto leadingChar =
              SM.extractText({SM.getCodeCompletionLoc().getAdvancedLoc(-1), 1});
          Lookup.setHaveLeadingSpace(leadingChar.find_first_of(" \t\f\v") !=
                                     StringRef::npos);
  
          if (isDynamicLookup(resultTy))
            Lookup.setIsDynamicLookup();
          Lookup.getValueExprCompletions(resultTy, /*VD=*/nullptr);
          Lookup.getOperatorCompletions(analyzedExpr, leadingSequenceExprs);
          Lookup.getPostfixKeywordCompletions(resultTy, analyzedExpr);
        }
      }
      break;
    }
  
    case CompletionKind::ReturnStmtExpr : {
      SourceLoc Loc = P.Context.SourceMgr.getCodeCompletionLoc();
      SmallVector<Type, 2> possibleReturnTypes;
      collectPossibleReturnTypesFromContext(CurDeclContext, possibleReturnTypes);
      Lookup.setExpectedTypes(possibleReturnTypes,
                              /*isImplicitSingleExpressionReturn*/ false);
      Lookup.getValueCompletionsInDeclContext(Loc);
      break;
    }
  
    case CompletionKind::YieldStmtExpr: {
      SourceLoc Loc = P.Context.SourceMgr.getCodeCompletionLoc();
      if (auto FD = dyn_cast<AccessorDecl>(CurDeclContext)) {
        if (FD->isCoroutine()) {
          // TODO: handle multi-value yields.
          Lookup.setExpectedTypes(FD->getStorage()->getValueInterfaceType(),
                                  /*isImplicitSingleExpressionReturn*/ false);
        }
      }
      Lookup.getValueCompletionsInDeclContext(Loc);
      break;
    }
  
    case CompletionKind::AfterPoundExpr: {
      ExprContextInfo ContextInfo(CurDeclContext, CodeCompleteTokenExpr);
      Lookup.setExpectedTypes(ContextInfo.getPossibleTypes(),
                              ContextInfo.isImplicitSingleExpressionReturn());
  
      Lookup.addPoundAvailable(ParentStmtKind);
      Lookup.addPoundLiteralCompletions(/*needPound=*/false);
      Lookup.addObjCPoundKeywordCompletions(/*needPound=*/false);
      break;
    }
  
    case CompletionKind::AfterPoundDirective: {
      addPoundDirectives(CompletionContext.getResultSink());
      // FIXME: Add pound expressions (e.g. '#selector()') if it's at statements
      // position.
      break;
    }
  
    case CompletionKind::PlatformConditon: {
      addPlatformConditions(CompletionContext.getResultSink());
      addConditionalCompilationFlags(CurDeclContext->getASTContext(),
                                     CompletionContext.getResultSink());
      break;
    }
  
    case CompletionKind::GenericRequirement: {
      auto Loc = Context.SourceMgr.getCodeCompletionLoc();
      Lookup.getGenericRequirementCompletions(CurDeclContext, Loc);
      break;
    }
    case CompletionKind::PrecedenceGroup:
      Lookup.getPrecedenceGroupCompletions(SyntxKind);
      break;
    case CompletionKind::StmtLabel: {
      SourceLoc Loc = P.Context.SourceMgr.getCodeCompletionLoc();
      Lookup.getStmtLabelCompletions(Loc, ParentStmtKind == StmtKind::Continue);
      break;
    }
    case CompletionKind::TypeAttrBeginning: {
      Lookup.getTypeAttributeKeywordCompletions();
  
      // Type names at attribute position after '@'.
      Lookup.getTypeCompletionsInDeclContext(
        P.Context.SourceMgr.getCodeCompletionLoc());
      break;
  
    }
    case CompletionKind::AfterIfStmtElse:
    case CompletionKind::CaseStmtKeyword:
    case CompletionKind::EffectsSpecifier:
    case CompletionKind::ForEachPatternBeginning:
      // Handled earlier by keyword completions.
      break;
    }
  
    deliverCompletionResults(CompletionContext, Lookup, CurDeclContext, Consumer);
  }
  
  void PrintingCodeCompletionConsumer::handleResults(
      CodeCompletionContext &context) {
    auto results = context.takeResults();
    handleResults(results);
  }
  
  void PrintingCodeCompletionConsumer::handleResults(
      MutableArrayRef<CodeCompletionResult *> Results) {
    unsigned NumResults = 0;
    for (auto Result : Results) {
      if (!IncludeKeywords && Result->getKind() == CodeCompletionResult::Keyword)
        continue;
      ++NumResults;
    }
    if (NumResults == 0)
      return;
  
    OS << "Begin completions, " << NumResults << " items\n";
    for (auto Result : Results) {
      if (!IncludeKeywords && Result->getKind() == CodeCompletionResult::Keyword)
        continue;
      Result->printPrefix(OS);
      if (PrintAnnotatedDescription) {
        printCodeCompletionResultDescriptionAnnotated(*Result, OS, /*leadingPunctuation=*/false);
        OS << "; typename=";
        printCodeCompletionResultTypeNameAnnotated(*Result, OS);
      } else {
        Result->getCompletionString()->print(OS);
      }
  
      OS << "; name=";
      printCodeCompletionResultFilterName(*Result, OS);
  
      if (IncludeSourceText) {
        OS << "; sourcetext=";
        SmallString<64> buf;
        {
          llvm::raw_svector_ostream bufOS(buf);
          printCodeCompletionResultSourceText(*Result, bufOS);
        }
        OS.write_escaped(buf);
      }
  
      StringRef comment = Result->getBriefDocComment();
      if (IncludeComments && !comment.empty()) {
        OS << "; comment=" << comment;
      }
  
      if (Result->getDiagnosticSeverity() !=
          CodeCompletionDiagnosticSeverity::None) {
        OS << "; diagnostics=" << comment;
        switch (Result->getDiagnosticSeverity()) {
        case CodeCompletionDiagnosticSeverity::Error:
          OS << "error";
          break;
        case CodeCompletionDiagnosticSeverity::Warning:
          OS << "warning";
          break;
        case CodeCompletionDiagnosticSeverity::Remark:
          OS << "remark";
          break;
        case CodeCompletionDiagnosticSeverity::Note:
          OS << "note";
          break;
        case CodeCompletionDiagnosticSeverity::None:
          llvm_unreachable("none");
        }
        OS << ":" << Result->getDiagnosticMessage();
      }
  
      OS << "\n";
    }
    OS << "End completions\n";
  }
  
  namespace {
  class CodeCompletionCallbacksFactoryImpl
      : public CodeCompletionCallbacksFactory {
    CodeCompletionContext &CompletionContext;
    CodeCompletionConsumer &Consumer;
  
  public:
    CodeCompletionCallbacksFactoryImpl(CodeCompletionContext &CompletionContext,
                                       CodeCompletionConsumer &Consumer)
        : CompletionContext(CompletionContext), Consumer(Consumer) {}
  
    CodeCompletionCallbacks *createCodeCompletionCallbacks(Parser &P) override {
      return new CodeCompletionCallbacksImpl(P, CompletionContext, Consumer);
    }
  };
  } // end anonymous namespace
  
  CodeCompletionCallbacksFactory *
  swift::ide::makeCodeCompletionCallbacksFactory(
      CodeCompletionContext &CompletionContext,
      CodeCompletionConsumer &Consumer) {
    return new CodeCompletionCallbacksFactoryImpl(CompletionContext, Consumer);
  }
  
  void swift::ide::lookupCodeCompletionResultsFromModule(
      CodeCompletionResultSink &targetSink, const ModuleDecl *module,
      ArrayRef<std::string> accessPath, bool needLeadingDot,
      const SourceFile *SF) {
    // Use the SourceFile as the decl context, to avoid decl context specific
    // behaviors.
    CompletionLookup Lookup(targetSink, module->getASTContext(), SF);
    Lookup.lookupExternalModuleDecls(module, accessPath, needLeadingDot);
  }
  
  MutableArrayRef<CodeCompletionResult *>
  swift::ide::copyCodeCompletionResults(CodeCompletionResultSink &targetSink,
                                        CodeCompletionResultSink &sourceSink,
                                        bool onlyTypes,
                                        bool onlyPrecedenceGroups) {
  
    // We will be adding foreign results (from another sink) into TargetSink.
    // TargetSink should have an owning pointer to the allocator that keeps the
    // results alive.
    targetSink.ForeignAllocators.push_back(sourceSink.Allocator);
    auto startSize = targetSink.Results.size();
  
    if (onlyTypes) {
      std::copy_if(sourceSink.Results.begin(), sourceSink.Results.end(),
                   std::back_inserter(targetSink.Results),
                   [](CodeCompletionResult *R) -> bool {
        if (R->getKind() != CodeCompletionResult::Declaration)
          return false;
        switch(R->getAssociatedDeclKind()) {
        case CodeCompletionDeclKind::Module:
        case CodeCompletionDeclKind::Class:
        case CodeCompletionDeclKind::Struct:
        case CodeCompletionDeclKind::Enum:
        case CodeCompletionDeclKind::Protocol:
        case CodeCompletionDeclKind::TypeAlias:
        case CodeCompletionDeclKind::AssociatedType:
        case CodeCompletionDeclKind::GenericTypeParam:
          return true;
        case CodeCompletionDeclKind::PrecedenceGroup:
        case CodeCompletionDeclKind::EnumElement:
        case CodeCompletionDeclKind::Constructor:
        case CodeCompletionDeclKind::Destructor:
        case CodeCompletionDeclKind::Subscript:
        case CodeCompletionDeclKind::StaticMethod:
        case CodeCompletionDeclKind::InstanceMethod:
        case CodeCompletionDeclKind::PrefixOperatorFunction:
        case CodeCompletionDeclKind::PostfixOperatorFunction:
        case CodeCompletionDeclKind::InfixOperatorFunction:
        case CodeCompletionDeclKind::FreeFunction:
        case CodeCompletionDeclKind::StaticVar:
        case CodeCompletionDeclKind::InstanceVar:
        case CodeCompletionDeclKind::LocalVar:
        case CodeCompletionDeclKind::GlobalVar:
          return false;
        }
  
        llvm_unreachable("Unhandled CodeCompletionDeclKind in switch.");
      });
    } else if (onlyPrecedenceGroups) {
      std::copy_if(sourceSink.Results.begin(), sourceSink.Results.end(),
                   std::back_inserter(targetSink.Results),
                   [](CodeCompletionResult *R) -> bool {
        return R->getAssociatedDeclKind() ==
                 CodeCompletionDeclKind::PrecedenceGroup;
      });
    } else {
      targetSink.Results.insert(targetSink.Results.end(),
                                sourceSink.Results.begin(),
                                sourceSink.Results.end());
    }
  
    return llvm::makeMutableArrayRef(targetSink.Results.data() + startSize,
                                     targetSink.Results.size() - startSize);
  }
  
  void SimpleCachingCodeCompletionConsumer::handleResultsAndModules(
      CodeCompletionContext &context,
      ArrayRef<RequestedCachedModule> requestedModules,
      DeclContext *DC) {
  
    // Use the current SourceFile as the DeclContext so that we can use it to
    // perform qualified lookup, and to get the correct visibility for
    // @testable imports. Also it cannot use 'DC' since it would apply decl
    // context changes to cached results.
    const SourceFile *SF = DC->getParentSourceFile();
  
    for (auto &R : requestedModules) {
      // FIXME(thread-safety): lock the whole AST context.  We might load a
      // module.
      llvm::Optional<CodeCompletionCache::ValueRefCntPtr> V =
          context.Cache.get(R.Key);
      if (!V.hasValue()) {
        // No cached results found. Fill the cache.
        V = context.Cache.createValue();
        CodeCompletionResultSink &Sink = (*V)->Sink;
        Sink.annotateResult = context.getAnnotateResult();
        Sink.addInitsToTopLevel = context.getAddInitsToTopLevel();
        Sink.enableCallPatternHeuristics = context.getCallPatternHeuristics();
        Sink.includeObjectLiterals = context.includeObjectLiterals();
        lookupCodeCompletionResultsFromModule(
            (*V)->Sink, R.TheModule, R.Key.AccessPath,
            R.Key.ResultsHaveLeadingDot, SF);
        context.Cache.set(R.Key, *V);
      }
      assert(V.hasValue());
      auto newItems =
          copyCodeCompletionResults(context.getResultSink(), (*V)->Sink,
                                    R.OnlyTypes, R.OnlyPrecedenceGroups);
      postProcessResults(newItems, context.CodeCompletionKind, DC,
                         &context.getResultSink());
    }
  
    handleResults(context);
  }
  
  //===----------------------------------------------------------------------===//
  // ImportDepth
  //===----------------------------------------------------------------------===//
  
  ImportDepth::ImportDepth(ASTContext &context,
                           const FrontendOptions &frontendOptions) {
    llvm::DenseSet<ModuleDecl *> seen;
    std::deque<std::pair<ModuleDecl *, uint8_t>> worklist;
  
    StringRef mainModule = frontendOptions.ModuleName;
    auto *main = context.getLoadedModule(context.getIdentifier(mainModule));
    assert(main && "missing main module");
    worklist.emplace_back(main, uint8_t(0));
  
    // Imports from -import-name such as Playground auxiliary sources are treated
    // specially by applying import depth 0.
    llvm::StringSet<> auxImports;
    for (const auto &pair : frontendOptions.getImplicitImportModuleNames())
      auxImports.insert(pair.first);
  
    // Private imports from this module.
    // FIXME: only the private imports from the current source file.
    // FIXME: ImportFilterKind::ShadowedByCrossImportOverlay?
    SmallVector<ImportedModule, 16> mainImports;
    main->getImportedModules(mainImports,
                             {ModuleDecl::ImportFilterKind::Default,
                              ModuleDecl::ImportFilterKind::ImplementationOnly});
    for (auto &import : mainImports) {
      uint8_t depth = 1;
      if (auxImports.count(import.importedModule->getName().str()))
        depth = 0;
      worklist.emplace_back(import.importedModule, depth);
    }
  
    // Fill depths with BFS over module imports.
    while (!worklist.empty()) {
      ModuleDecl *module;
      uint8_t depth;
      std::tie(module, depth) = worklist.front();
      worklist.pop_front();
  
      if (!seen.insert(module).second)
        continue;
  
      // Insert new module:depth mapping.
      const clang::Module *CM = module->findUnderlyingClangModule();
      if (CM) {
        depths[CM->getFullModuleName()] = depth;
      } else {
        depths[module->getName().str()] = depth;
      }
  
      // Add imports to the worklist.
      SmallVector<ImportedModule, 16> imports;
      module->getImportedModules(imports);
      for (auto &import : imports) {
        uint8_t next = std::max(depth, uint8_t(depth + 1)); // unsigned wrap
  
        // Implicitly imported sub-modules get the same depth as their parent.
        if (const clang::Module *CMI =
                import.importedModule->findUnderlyingClangModule())
          if (CM && CMI->isSubModuleOf(CM))
            next = depth;
        worklist.emplace_back(import.importedModule, next);
      }
    }
  }
  