//===--- APIDiffMigratorPass.cpp ------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 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/AST/USRGeneration.h"
#include "swift/AST/ASTVisitor.h"
#include "swift/Basic/StringExtras.h"
#include "swift/Frontend/Frontend.h"
#include "swift/IDE/Utils.h"
#include "swift/Sema/IDETypeChecking.h"
#include "swift/Migrator/ASTMigratorPass.h"
#include "swift/Migrator/EditorAdapter.h"
#include "swift/Migrator/FixitApplyDiagnosticConsumer.h"
#include "swift/Migrator/Migrator.h"
#include "swift/Migrator/RewriteBufferEditsReceiver.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/FileManager.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Edit/EditedSource.h"
#include "clang/Rewrite/Core/RewriteBuffer.h"
#include "llvm/Support/FileSystem.h"
#include "swift/IDE/APIDigesterData.h"
#include "swift/Basic/Defer.h"

using namespace swift;
using namespace swift::migrator;
using namespace swift::ide;
using namespace swift::ide::api;

namespace {

struct FoundResult {
  SourceRange TokenRange;
  bool Optional; // Range includes a trailing ? or !, e.g. [SomeType!]
  bool Suffixable; // No need to wrap parens when adding optionality
  bool Suffixed; // Range is followed by a trailing ? or !, e.g. [SomeType]!
  bool isValid() const { return TokenRange.isValid(); }
};

class ChildIndexFinder : public TypeReprVisitor<ChildIndexFinder, FoundResult> {
  ArrayRef<uint8_t> ChildIndices;
  bool ParentIsOptional;
  bool IsFunctionTypeArgument;

public:
  ChildIndexFinder(ArrayRef<uint8_t> ChildIndices)
      : ChildIndices(ChildIndices), ParentIsOptional(false),
        IsFunctionTypeArgument(false) {}

  FoundResult findChild(AbstractFunctionDecl *Parent) {
    auto NextIndex = consumeNext();
    if (!NextIndex) {
      if (auto Func = dyn_cast<FuncDecl>(Parent))
        return findChild(Func->getBodyResultTypeLoc());
      if (auto Init = dyn_cast<ConstructorDecl>(Parent)) {
        SourceLoc End = Init->getFailabilityLoc();
        bool Optional = End.isValid();
        if (!Optional)
          End = Init->getNameLoc();
        return {SourceRange(Init->getNameLoc(), End), Optional,
          /*suffixable=*/true, /*suffixed=*/false};
      }
      return {SourceRange(), false, false, false};
    }

    for (auto *Param: *Parent->getParameters()) {
      if (!--NextIndex) {
        return findChild(Param->getTypeRepr());
      }
    }
    llvm_unreachable("child index out of bounds");
  }

private:
  bool hasNextIndex() const {
    return !ChildIndices.empty();
  }

  unsigned consumeNext() {
    unsigned Next = ChildIndices.front();
    ChildIndices = ChildIndices.drop_front();
    return Next;
  }

  bool isUserTypeAlias(TypeRepr *T) const {
    if (auto Ident = dyn_cast<ComponentIdentTypeRepr>(T)) {
      if (auto Bound = Ident->getBoundDecl()) {
        return isa<TypeAliasDecl>(Bound) &&
          !Bound->getModuleContext()->isSystemModule();
      }
    }
    return false;
  }

  FoundResult findChild(TypeLoc Loc) {
    if (!Loc.hasLocation())
      return {SourceRange(), false, false, false};
    return visit(Loc.getTypeRepr());
  }

public:

  template<typename T>
  FoundResult handleParent(TypeRepr *Parent, const ArrayRef<T> Children,
                           bool Optional = false, bool Suffixable = true) {
    if (!hasNextIndex())
      return {
        Parent->getSourceRange(),
        Optional, Suffixable, /*Suffixed=*/ParentIsOptional
      };

    auto NextIndex = consumeNext();
    if (isUserTypeAlias(Parent))
      return {SourceRange(), false, false, false};

    assert(NextIndex < Children.size());
    TypeRepr *Child = Children[NextIndex];
    ParentIsOptional = Optional;
    IsFunctionTypeArgument = NextIndex == 1 && isa<FunctionTypeRepr>(Parent);

    return visit(Child);
  }

  FoundResult handleParent(TypeRepr *Parent, TypeRepr *FirstChild,
                           TypeRepr *SecondChild, bool Optional = false,
                           bool Suffixable = true) {
    TypeRepr *Children[] = {FirstChild, SecondChild};
    return handleParent(Parent, llvm::makeArrayRef(Children), Optional,
                        Suffixable);
  }

  FoundResult handleParent(TypeRepr *Parent, TypeRepr *Base,
                           bool Optional = false, bool Suffixable = true) {
    return handleParent(Parent, llvm::makeArrayRef(Base), Optional, Suffixable);
  }

  FoundResult visitTypeRepr(TypeRepr *T) {
    llvm_unreachable("unexpected typerepr");
  }

  FoundResult visitErrorTypeRepr(ErrorTypeRepr *T) {
    return {SourceRange(), false, false, false};
  }

  FoundResult visitAttributedTypeRepr(AttributedTypeRepr *T) {
    return visit(T->getTypeRepr());
  }

  FoundResult visitInOutTypeRepr(InOutTypeRepr *T) {
    return visit(T->getBase());
  }

  FoundResult visitSharedTypeRepr(SharedTypeRepr *T) {
    return visit(T->getBase());
  }

  FoundResult visitOwnedTypeRepr(OwnedTypeRepr *T) {
    return visit(T->getBase());
  }

  FoundResult visitArrayTypeRepr(ArrayTypeRepr *T) {
    return handleParent(T, T->getBase());
  }

  FoundResult visitDictionaryTypeRepr(DictionaryTypeRepr *T) {
    return handleParent(T, T->getKey(), T->getValue());
  }

  FoundResult visitTupleTypeRepr(TupleTypeRepr *T) {
    // Paren TupleTypeReprs may be arbitrarily nested so don't count as their
    // own index level except in the case of function type argument parens
    if (T->isParenType() && !IsFunctionTypeArgument) {
      ParentIsOptional = false;
      return visit(T->getElementType(0));
    }

    IsFunctionTypeArgument = false;
    llvm::SmallVector<TypeRepr *, 8> Children;
    T->getElementTypes(Children);
    return handleParent(T, ArrayRef<TypeRepr *>(Children));
  }

  FoundResult visitFunctionTypeRepr(FunctionTypeRepr *T) {
    return handleParent(T, T->getResultTypeRepr(), T->getArgsTypeRepr(),
                       /*Optional=*/false, /*Suffixable=*/false);
  }

  FoundResult visitCompositionTypeRepr(CompositionTypeRepr *T) {
    return handleParent(T, T->getTypes(), /*Optional=*/false,
                        /*Suffixable=*/false);
  }

  FoundResult visitSimpleIdentTypeRepr(SimpleIdentTypeRepr *T) {
    return handleParent(T, ArrayRef<TypeRepr*>());
  }

  FoundResult visitGenericIdentTypeRepr(GenericIdentTypeRepr *T) {
    return handleParent(T, T->getGenericArgs());
  }

  FoundResult visitCompoundIdentTypeRepr(CompoundIdentTypeRepr *T) {
    return visit(T->getComponents().back());
  }

  FoundResult visitOptionalTypeRepr(OptionalTypeRepr *T) {
    return handleParent(T, T->getBase(), /*Optional=*/true);
  }

  FoundResult visitImplicitlyUnwrappedOptionalTypeRepr(ImplicitlyUnwrappedOptionalTypeRepr *T) {
    return handleParent(T, T->getBase(), /*Optional=*/true);
  }

  FoundResult visitProtocolTypeRepr(ProtocolTypeRepr *T) {
    return handleParent(T, T->getBase());
  }

  FoundResult visitMetatypeTypeRepr(MetatypeTypeRepr *T) {
    return handleParent(T, T->getBase());
  }

  FoundResult visitFixedTypeRepr(FixedTypeRepr *T) {
    return handleParent(T, ArrayRef<TypeRepr*>());
  }
};

static ValueDecl* getReferencedDecl(Expr *E) {
  // Get the syntactic expression out of an implicit expression.
  if (auto *ICE = dyn_cast<ImplicitConversionExpr>(E))
    E = ICE->getSyntacticSubExpr();
  if (auto *DRE = dyn_cast<DeclRefExpr>(E)) {
    return DRE->getDecl();
  } else if (auto *MRE = dyn_cast<MemberRefExpr>(E)) {
    return MRE->getMember().getDecl();
  } else if (auto OtherCtorE = dyn_cast<OtherConstructorDeclRefExpr>(E)) {
    return OtherCtorE->getDecl();
  } else {
    return nullptr;
  }
}

struct ConversionFunctionInfo {
  Expr *ExpressionToWrap;
  SmallString<256> Buffer;
  unsigned FuncNameStart;
  unsigned FuncNameEnd;
  ConversionFunctionInfo(Expr *ExpressionToWrap):
    ExpressionToWrap(ExpressionToWrap) {}
  StringRef getFuncDef() const { return Buffer.str(); }
  StringRef getFuncName() const {
    return Buffer.substr(FuncNameStart, FuncNameEnd - FuncNameStart);
  }
};

struct APIDiffMigratorPass : public ASTMigratorPass, public SourceEntityWalker {

  APIDiffItemStore DiffStore;

  bool isNilExpr(Expr *E) {
    auto Range = E->getSourceRange();
    return Range.isValid() && Lexer::getCharSourceRangeFromSourceRange(
      SF->getASTContext().SourceMgr, Range).str() == "nil";
  }

  bool isDotMember(CharSourceRange Range) {
    auto S = Range.str();
    return S.startswith(".") && S.substr(1).find(".") == StringRef::npos;
  }

  bool isDotMember(SourceRange Range) {
    return isDotMember(Lexer::getCharSourceRangeFromSourceRange(
      SF->getASTContext().SourceMgr, Range));
  }

  bool isDotMember(Expr *E) {
    auto Range = E->getSourceRange();
    return Range.isValid() && isDotMember(Range);
  }

  std::vector<APIDiffItem*> getRelatedDiffItems(ValueDecl *VD) {
    std::vector<APIDiffItem*> results;
    if (!VD)
      return results;
    auto addDiffItems = [&](ValueDecl *VD) {
      llvm::SmallString<64> Buffer;
      llvm::raw_svector_ostream OS(Buffer);
      if (swift::ide::printValueDeclUSR(VD, OS))
        return;
      auto Items = DiffStore.getDiffItems(Buffer.str());
      results.insert(results.end(), Items.begin(), Items.end());
    };

    addDiffItems(VD);
    for (auto *Overridden: collectAllOverriddenDecls(VD,
                                                     /*IncludeProtocolReqs=*/true,
                                                     /*Transitive=*/true)) {
      addDiffItems(Overridden);
    }
    return results;
  }

  DeclNameViewer getFuncRename(ValueDecl *VD, llvm::SmallString<32> &Buffer,
                               bool &IgnoreBase) {
    for (auto *Item: getRelatedDiffItems(VD)) {
      if (auto *CI = dyn_cast<CommonDiffItem>(Item)) {
        if (CI->isRename()) {
          IgnoreBase = true;
          switch(CI->NodeKind) {
          case SDKNodeKind::DeclFunction:
            IgnoreBase = false;
            LLVM_FALLTHROUGH;
          case SDKNodeKind::DeclConstructor:
            return DeclNameViewer(CI->getNewName());
          default:
            return DeclNameViewer();
          }
        }
      }
      if (auto *MI = dyn_cast<TypeMemberDiffItem>(Item)) {
        if (MI->Subkind == TypeMemberDiffItemSubKind::FuncRename) {
          llvm::raw_svector_ostream OS(Buffer);
          OS << MI->getNewTypeAndDot() << MI->newPrintedName;
          return DeclNameViewer(OS.str());
        }
      }
    }
    return DeclNameViewer();
  }


  bool isSimpleReplacement(APIDiffItem *Item, bool isDotMember, std::string &Text) {
    if (auto *MD = dyn_cast<TypeMemberDiffItem>(Item)) {
      if (MD->Subkind == TypeMemberDiffItemSubKind::SimpleReplacement) {
        bool NeedNoTypeName = isDotMember &&
          MD->oldPrintedName == MD->newPrintedName;
        if (NeedNoTypeName) {
          Text = (llvm::Twine(MD->isNewNameGlobal() ? "" : ".") +
            MD->getNewName().base()).str();
        } else {
          Text = (llvm::Twine(MD->getNewTypeAndDot()) +
            MD->getNewName().base()).str();
        }
        return true;
      }
    }

    // Simple rename.
    if (auto CI = dyn_cast<CommonDiffItem>(Item)) {
      if (CI->isRename() && (CI->NodeKind == SDKNodeKind::DeclVar ||
                             CI->NodeKind == SDKNodeKind::DeclType)) {
        Text = CI->getNewName();
        return true;
      }
    }
    return false;
  }

  std::vector<ConversionFunctionInfo> HelperFuncInfo;
  SourceLoc FileEndLoc;
  llvm::StringSet<> OverridingRemoveNames;

  /// For a given expression, check whether the type of this expression is
  /// type alias type, and the type alias type is known to change to raw
  /// representable type.
  bool isRecognizedTypeAliasChange(Expr *E) {
    if (auto Ty = E->getType()) {
      if (auto *NT = dyn_cast<TypeAliasType>(Ty.getPointer())) {
        for (auto Item: getRelatedDiffItems(NT->getDecl())) {
          if (auto CI = dyn_cast<CommonDiffItem>(Item)) {
            if (CI->DiffKind == NodeAnnotation::TypeAliasDeclToRawRepresentable) {
              return true;
            }
          }
        }
      }
    }
    return false;
  }

  APIDiffMigratorPass(EditorAdapter &Editor, SourceFile *SF,
                      const MigratorOptions &Opts):
    ASTMigratorPass(Editor, SF, Opts), DiffStore(Diags),
    FileEndLoc(SM.getRangeForBuffer(BufferID).getEnd()),
    OverridingRemoveNames(funcNamesForOverrideRemoval()) {}

  ~APIDiffMigratorPass() {
    Editor.disableCache();
    SWIFT_DEFER { Editor.enableCache(); };

    // Collect inserted functions to avoid re-insertion.
    std::set<std::string> InsertedFunctions;
    SmallVector<Decl*, 16> TopDecls;
    SF->getTopLevelDecls(TopDecls);
    for (auto *D: TopDecls) {
      if (auto *FD = dyn_cast<FuncDecl>(D)) {
        InsertedFunctions.insert(FD->getBaseName().getIdentifier().str());
      }
    }

    // Handle helper functions without wrappees first.
    for (auto &Cur: HelperFuncInfo) {
      if (Cur.ExpressionToWrap)
        continue;
      auto FuncName = Cur.getFuncName();
      // Avoid inserting the helper function if it's already present.
      if (!InsertedFunctions.count(FuncName)) {
        Editor.insert(FileEndLoc, Cur.getFuncDef());
        InsertedFunctions.insert(FuncName);
      }
    }

    // Remove all helper functions that're without expressions to wrap.
    HelperFuncInfo.erase(std::remove_if(HelperFuncInfo.begin(),
      HelperFuncInfo.end(), [](const ConversionFunctionInfo& Info) {
        return !Info.ExpressionToWrap;
    }), HelperFuncInfo.end());

    for (auto &Cur: HelperFuncInfo) {
      assert(Cur.ExpressionToWrap);
      // Avoid wrapping nil expression.
      if (isNilExpr(Cur.ExpressionToWrap))
        continue;

      // Avoid wrapping a single expression with multiple conversion functions.
      auto count = std::count_if(HelperFuncInfo.begin(), HelperFuncInfo.end(),
        [&] (ConversionFunctionInfo &Info) {
          return Info.ExpressionToWrap->getSourceRange() ==
            Cur.ExpressionToWrap->getSourceRange();
        });
      if (count > 1)
        continue;
      assert(count == 1);

      // A conversion function will be redundant if the expression will change
      // from type alias to raw-value representable.
      if (isRecognizedTypeAliasChange(Cur.ExpressionToWrap))
        continue;
      auto FuncName = Cur.getFuncName();

      // Avoid inserting the helper function if it's already present.
      if (!InsertedFunctions.count(FuncName)) {
        Editor.insert(FileEndLoc, Cur.getFuncDef());
        InsertedFunctions.insert(FuncName);
      }
      Editor.insertBefore(Cur.ExpressionToWrap->getStartLoc(),
        (Twine(FuncName) + "(").str());
      Editor.insertAfterToken(Cur.ExpressionToWrap->getEndLoc(), ")");
    }
  }

  void run() {
    if (Opts.APIDigesterDataStorePaths.empty())
      return;
    for (auto Path : Opts.APIDigesterDataStorePaths)
      DiffStore.addStorePath(Path);
    DiffStore.printIncomingUsr(Opts.DumpUsr);
    walk(SF);
  }

  bool updateStringRepresentableDeclRef(APIDiffItem *Diff,
      CharSourceRange Range) {
    auto *CD = dyn_cast<CommonDiffItem>(Diff);
    if (!CD)
      return false;
    if (CD->NodeKind != SDKNodeKind::DeclVar)
      return false;
    if (!CD->isStringRepresentableChange())
      return false;
    switch(CD->DiffKind) {
    case NodeAnnotation::SimpleStringRepresentableUpdate:
      Editor.insert(Range.getEnd(), ".rawValue");
      return true;
    default:
      return false;
    }
  }

  bool visitDeclReference(ValueDecl *D, CharSourceRange Range,
                          TypeDecl *CtorTyRef, ExtensionDecl *ExtTyRef,
                          Type T, ReferenceMetaData Data) override {
    if (Data.isImplicit)
      return true;

    for (auto *Item: getRelatedDiffItems(CtorTyRef ? CtorTyRef: D)) {
      std::string RepText;
      if (isSimpleReplacement(Item, isDotMember(Range), RepText)) {
        Editor.replace(Range, RepText);
        return true;
      }
    }
    return true;
  }

  struct ReferenceCollector : public SourceEntityWalker {
    ValueDecl *Target;
    CharSourceRange Result;
    ReferenceCollector(ValueDecl* Target) : Target(Target) {}
    bool visitDeclReference(ValueDecl *D, CharSourceRange Range,
                            TypeDecl *CtorTyRef, ExtensionDecl *ExtTyRef,
                            Type T, ReferenceMetaData Data) override {
      if (D == Target && !Data.isImplicit) {
        Result = Range;
        return false;
      }
      return true;
    }
  };

  void emitRenameLabelChanges(Expr *Arg, DeclNameViewer NewName,
                              llvm::ArrayRef<unsigned> IgnoreArgIndex) {
    unsigned Idx = 0;
    auto Ranges = getCallArgLabelRanges(SM, Arg,
                                        LabelRangeEndAt::LabelNameOnly);
    llvm::SmallVector<uint8_t, 2> ToRemoveIndices;
    for (unsigned I = 0; I < Ranges.size(); I ++) {
      if (std::any_of(IgnoreArgIndex.begin(), IgnoreArgIndex.end(),
                      [I](unsigned Ig) { return Ig == I; }))
        continue;
      auto LR = Ranges[I];
      if (Idx < NewName.argSize()) {
        auto Label = NewName.args()[Idx++];

        if (!Label.empty()) {
          if (LR.getByteLength())
            Editor.replace(LR, Label);
          else
            Editor.insert(LR.getStart(), (llvm::Twine(Label) + ": ").str());
        } else if (LR.getByteLength()){
          // New label is "_" however the old label is explicit.
          ToRemoveIndices.push_back(I);
        }
      }
    }
    if (!ToRemoveIndices.empty()) {
      auto Ranges = getCallArgLabelRanges(SM, Arg,
                                         LabelRangeEndAt::BeforeElemStart);
      for (auto I : ToRemoveIndices) {
        Editor.remove(Ranges[I]);
      }
    }
  }

  void handleFuncRename(ValueDecl *FD, Expr* FuncRefContainer, Expr *Arg) {
    bool IgnoreBase = false;
    llvm::SmallString<32> Buffer;
    if (auto View = getFuncRename(FD, Buffer, IgnoreBase)) {
      if (!IgnoreBase) {
        ReferenceCollector Walker(FD);
        Walker.walk(FuncRefContainer);
        Editor.replace(Walker.Result, View.base());
      }
      emitRenameLabelChanges(Arg, View, {});
    }
  }

  bool handleQualifiedReplacement(Expr* Call) {
    auto handleDecl = [&](ValueDecl *VD, SourceRange ToReplace) {
      for (auto *I: getRelatedDiffItems(VD)) {
        if (auto *Item = dyn_cast<TypeMemberDiffItem>(I)) {
          if (Item->Subkind == TypeMemberDiffItemSubKind::QualifiedReplacement) {
            bool NeedNoTypeName = isDotMember(ToReplace) &&
              Item->oldPrintedName == Item->newPrintedName;
            if (NeedNoTypeName) {
              Editor.replace(ToReplace,
                (llvm::Twine(Item->isNewNameGlobal() ? "" : ".") +
                Item->getNewName().base()).str());
            } else {
              Editor.replace(ToReplace,
                (llvm::Twine(Item->getNewTypeAndDot()) +
                  Item->getNewName().base()).str());
            }
            return true;
          }
        }
      }
      return false;
    };
    if (auto *DSC = dyn_cast<DotSyntaxCallExpr>(Call)) {
      if (auto FD = DSC->getFn()->getReferencedDecl().getDecl()) {
        if (handleDecl(FD, Call->getSourceRange()))
          return true;
      }
    } else if (auto MRE = dyn_cast<MemberRefExpr>(Call)) {
      if (handleDecl(MRE->getReferencedDecl().getDecl(), MRE->getSourceRange()))
        return true;
    }
    return false;
  }

  bool handleSpecialCases(ValueDecl *FD, CallExpr* Call, Expr *Arg) {
    SpecialCaseDiffItem *Item = nullptr;
    for (auto *I: getRelatedDiffItems(FD)) {
      Item = dyn_cast<SpecialCaseDiffItem>(I);
      if (Item)
        break;
    }
    if (!Item)
      return false;
    std::vector<CallArgInfo> AllArgs =
      getCallArgInfo(SM, Arg, LabelRangeEndAt::LabelNameOnly);
    switch(Item->caseId) {
    case SpecialCaseId::NSOpenGLSetOption: {
      // swift 3.2:
      // NSOpenGLSetOption(NSOpenGLGOFormatCacheSize, 5)
      // swift 4:
      // NSOpenGLGOFormatCacheSize.globalValue = 5
      CallArgInfo &FirstArg = AllArgs[0];
      CallArgInfo &SecondArg = AllArgs[1];
      Editor.remove(CharSourceRange(SM, Call->getStartLoc(),
                                    FirstArg.ArgExp->getStartLoc()));
      Editor.replace(CharSourceRange(SM, Lexer::getLocForEndOfToken(SM,
        FirstArg.ArgExp->getEndLoc()), SecondArg.LabelRange.getStart()),
                     ".globalValue = ");
      Editor.remove(Call->getEndLoc());
      return true;
    }
    case SpecialCaseId::NSOpenGLGetOption: {
      // swift 3.2:
      // NSOpenGLGetOption(NSOpenGLGOFormatCacheSize, &cacheSize)
      // swift 4:
      // cacheSize = NSOpenGLGOFormatCacheSize.globalValue
      CallArgInfo &FirstArg = AllArgs[0];
      CallArgInfo &SecondArg = AllArgs[1];

      StringRef SecondArgContent = SecondArg.getEntireCharRange(SM).str();
      if (SecondArgContent[0] == '&')
        SecondArgContent = SecondArgContent.substr(1);

      Editor.replace(CharSourceRange(SM, Call->getStartLoc(),
                                     FirstArg.ArgExp->getStartLoc()),
                     (llvm::Twine(SecondArgContent) + " = ").str());
      Editor.replace(CharSourceRange(SM, FirstArg.getEntireCharRange(SM).getEnd(),
                                     Lexer::getLocForEndOfToken(SM, Call->getEndLoc())),
                     ".globalValue");
      return true;
    }
    case SpecialCaseId::StaticAbsToSwiftAbs:
      // swift 3:
      // CGFloat.abs(1.0)
      // Float.abs(1.0)
      // Double.abs(1.0)
      // Float80.abs(1.0)
      //
      // swift 4:
      // Swift.abs(1.0)
      // Swift.abs(1.0)
      // Swift.abs(1.0)
      // Swift.abs(1.0)
      Editor.replace(Call->getFn()->getSourceRange(), "Swift.abs");
      return true;
    case SpecialCaseId::ToUIntMax:
      if (const auto *DotCall = dyn_cast<DotSyntaxCallExpr>(Call->getFn())) {
        Editor.insert(DotCall->getStartLoc(), "UInt64(");
        Editor.replace({ DotCall->getDotLoc(), Call->getEndLoc() }, ")");
        return true;
      }
      return false;
    case SpecialCaseId::ToIntMax:
      if (const auto *DotCall = dyn_cast<DotSyntaxCallExpr>(Call->getFn())) {
        Editor.insert(DotCall->getStartLoc(), "Int64(");
        Editor.replace({ DotCall->getDotLoc(), Call->getEndLoc() }, ")");
        return true;
      }
      return false;
    case SpecialCaseId::NSOpenGLGetVersion: {
      if (const auto *Tuple = dyn_cast<TupleExpr>(Arg)) {
        if (Tuple->getNumElements() != 2) {
          return false;
        }

        auto extractArg = [](const Expr *Arg) -> const DeclRefExpr * {
          while (const auto *ICE = dyn_cast<ImplicitConversionExpr>(Arg)) {
            Arg = ICE->getSubExpr();
          }
          if (const auto *IOE = dyn_cast<InOutExpr>(Arg)) {
            return dyn_cast<DeclRefExpr>(IOE->getSubExpr());
          }
          return nullptr;
        };

        const auto *Arg0 = extractArg(Tuple->getElement(0));
        const auto *Arg1 = extractArg(Tuple->getElement(1));

        if (!(Arg0 && Arg1)) {
          return false;
        }
        SmallString<256> Scratch;
        llvm::raw_svector_ostream OS(Scratch);
        auto StartLoc = Call->getStartLoc();
        Editor.insert(StartLoc, "(");
        Editor.insert(StartLoc,
          SM.extractText(Lexer::getCharSourceRangeFromSourceRange(SM,
            Arg0->getSourceRange())));
        Editor.insert(StartLoc, ", ");
        Editor.insert(StartLoc,
          SM.extractText(Lexer::getCharSourceRangeFromSourceRange(SM,
            Arg1->getSourceRange())));
        Editor.insert(StartLoc, ") = ");
        Editor.replace(Call->getSourceRange(), "NSOpenGLContext.openGLVersion");
        return true;
      }
      return false;
    }
    case SpecialCaseId::UIApplicationMain: {
      // If the first argument is CommandLine.argc, replace the second argument
      // with CommandLine.unsafeArgv
      CallArgInfo &FirstArg = AllArgs[0];
      // handle whitespace/line splits around the first arg when matching
      auto FirstArgSplit =
        SM.extractText(FirstArg.getEntireCharRange(SM)).rsplit('.');
      if (!FirstArgSplit.second.empty() &&
          FirstArgSplit.first.trim() == "CommandLine" &&
          FirstArgSplit.second.trim() == "argc") {
        CallArgInfo &SecondArg = AllArgs[1];
        Editor.replace(SecondArg.getEntireCharRange(SM),
                       "CommandLine.unsafeArgv");
        return true;
      }
      return false;
    }
    }
    llvm_unreachable("unhandled case");
  }

  bool handleTypeHoist(ValueDecl *FD, CallExpr* Call, Expr *Arg) {
    TypeMemberDiffItem *Item = nullptr;
    for (auto *I: getRelatedDiffItems(FD)) {
      Item = dyn_cast<TypeMemberDiffItem>(I);
      if (Item)
        break;
    }
    if (!Item)
      return false;
    if (Item->Subkind == TypeMemberDiffItemSubKind::SimpleReplacement ||
        Item->Subkind == TypeMemberDiffItemSubKind::QualifiedReplacement ||
        Item->Subkind == TypeMemberDiffItemSubKind::FuncRename)
      return false;

    if (Item->Subkind == TypeMemberDiffItemSubKind::GlobalFuncToStaticProperty) {
      Editor.replace(Call->getSourceRange(),
        (llvm::Twine(Item->getNewTypeAndDot()) + Item->getNewName().base()).str());
      return true;
    }
    if (*Item->selfIndex)
      return false;
    std::vector<CallArgInfo> AllArgs =
      getCallArgInfo(SM, Arg, LabelRangeEndAt::LabelNameOnly);
    if (!AllArgs.size())
      return false;
    assert(*Item->selfIndex == 0 && "we cannot handle otherwise");
    DeclNameViewer NewName = Item->getNewName();
    llvm::SmallVector<unsigned, 2> IgnoredArgIndices;
    IgnoredArgIndices.push_back(*Item->selfIndex);
    if (auto RI = Item->removedIndex)
      IgnoredArgIndices.push_back(*RI);
    emitRenameLabelChanges(Arg, NewName, IgnoredArgIndices);
    auto *SelfExpr = AllArgs[0].ArgExp;
    if (auto *IOE = dyn_cast<InOutExpr>(SelfExpr))
      SelfExpr = IOE->getSubExpr();
    const bool NeedParen = !SelfExpr->canAppendPostfixExpression();

    // Remove the global function name: "Foo(a, b..." to "a, b..."
    Editor.remove(CharSourceRange(SM, Call->getStartLoc(),
                                  SelfExpr->getStartLoc()));
    if (NeedParen)
      Editor.insert(SelfExpr->getStartLoc(), "(");
    std::string MemberFuncBase;
    if (Item->Subkind == TypeMemberDiffItemSubKind::HoistSelfAndUseProperty)
      MemberFuncBase = (llvm::Twine(NeedParen ? ")." : ".") + Item->getNewName().
        base()).str();
    else
      MemberFuncBase = (llvm::Twine(NeedParen ? ")." : ".") + Item->getNewName().
        base() + "(").str();

    if (AllArgs.size() > 1) {
      Editor.replace(CharSourceRange(SM, Lexer::getLocForEndOfToken(SM,
        SelfExpr->getEndLoc()), AllArgs[1].LabelRange.getStart()),
                     MemberFuncBase);
    } else {
      Editor.insert(Lexer::getLocForEndOfToken(SM, SelfExpr->getEndLoc()),
                    MemberFuncBase);
    }

    switch (Item->Subkind) {
    case TypeMemberDiffItemSubKind::FuncRename:
    case TypeMemberDiffItemSubKind::GlobalFuncToStaticProperty:
    case TypeMemberDiffItemSubKind::SimpleReplacement:
    case TypeMemberDiffItemSubKind::QualifiedReplacement:
      llvm_unreachable("should be handled elsewhere");
    case TypeMemberDiffItemSubKind::HoistSelfOnly:
      // we are done here.
      return true;
    case TypeMemberDiffItemSubKind::HoistSelfAndRemoveParam: {
      unsigned RI = *Item->removedIndex;
      CallArgInfo &ToRemove = AllArgs[RI];
      if (AllArgs.size() == RI + 1) {
        Editor.remove(ToRemove.getEntireCharRange(SM));
      } else {
        CallArgInfo &AfterToRemove = AllArgs[RI + 1];
        Editor.remove(CharSourceRange(SM, ToRemove.LabelRange.getStart(),
                                      AfterToRemove.LabelRange.getStart()));
      }
      return true;
    }
    case TypeMemberDiffItemSubKind::HoistSelfAndUseProperty:
      // Remove ).
      Editor.remove(Arg->getEndLoc());
      return true;
    }
    llvm_unreachable("unhandled subkind");
  }

  void handleFunctionCallToPropertyChange(ValueDecl *FD, Expr* FuncRefContainer,
                                          Expr *Arg) {
    for (auto *Item : getRelatedDiffItems(FD)) {
      if (auto *CD = dyn_cast<CommonDiffItem>(Item)) {
        switch (CD->DiffKind) {
        case NodeAnnotation::GetterToProperty: {
          // Remove "()"
          Editor.remove(Lexer::getCharSourceRangeFromSourceRange(SM,
                                                        Arg->getSourceRange()));
          return;
        }
        case NodeAnnotation::SetterToProperty: {
          ReferenceCollector Walker(FD);
          Walker.walk(FuncRefContainer);
          auto ReplaceRange = CharSourceRange(SM, Walker.Result.getStart(),
                                          Arg->getStartLoc().getAdvancedLoc(1));

          // Replace "x.getY(" with "x.Y =".
          auto Replacement = (llvm::Twine(Walker.Result.str()
                                          .substr(3)) + " = ").str();
          SmallString<64> Scratch;
          Editor.replace(ReplaceRange,
                         camel_case::toLowercaseInitialisms(Replacement, Scratch));

          // Remove ")"
          Editor.remove(CharSourceRange(SM, Arg->getEndLoc(), Arg->getEndLoc().
                                        getAdvancedLoc(1)));
          return;
        }
        default:
          break;
        }
      }
    }
  }

  void replaceExpr(Expr* E, StringRef Text) {
    Editor.replace(CharSourceRange(SM, E->getStartLoc(),
      Lexer::getLocForEndOfToken(SM, E->getEndLoc())), Text);
  }

  bool wrapAttributeReference(Expr* Reference, Expr* WrapperTarget,
                              bool FromString) {
    auto *RD = getReferencedDecl(Reference);
    if (!RD)
      return false;
    std::string Rename;
    Optional<NodeAnnotation> Kind;
    StringRef LeftComment;
    StringRef RightComment;
    for (auto *Item: getRelatedDiffItems(RD)) {
      if (isSimpleReplacement(Item, isDotMember(Reference), Rename)) {
      } else if (auto *CI = dyn_cast<CommonDiffItem>(Item)) {
        if (CI->isStringRepresentableChange() &&
            CI->NodeKind == SDKNodeKind::DeclVar) {
          Kind = CI->DiffKind;
          LeftComment = CI->LeftComment;
          RightComment = CI->RightComment;
        }
      }
    }
    if (!Kind.hasValue())
      return false;
    if (Kind) {
      insertHelperFunction(*Kind, LeftComment, RightComment, FromString,
        WrapperTarget);
    }
    if (!Rename.empty()) {
      replaceExpr(Reference, Rename);
    }
    return true;
  }

  bool handleAssignDestMigration(Expr *E) {
    auto *ASE = dyn_cast<AssignExpr>(E);
    if (!ASE || !ASE->getDest() || !ASE->getSrc())
      return false;
    auto *Dest = ASE->getDest();
    auto Src = ASE->getSrc();
    if (wrapAttributeReference(Dest, Src, true)) {
      // We should handle the assignment source here since we won't visit
      // the children with present changes.
      handleAttributeReference(Src);
      return true;
    }
    return false;
  }

  bool handleAttributeReference(Expr *E) {
    return wrapAttributeReference(E, E, false);
  }

  ConversionFunctionInfo &insertHelperFunction(NodeAnnotation Anno,
                                               StringRef RawType,
                                               StringRef NewType,
                                               bool FromString,
                                               Expr *Wrappee) {
    HelperFuncInfo.emplace_back(Wrappee);
    ConversionFunctionInfo &Info = HelperFuncInfo.back();
    llvm::raw_svector_ostream OS(Info.Buffer);
    OS << "\n";
    OS << "// Helper function inserted by Swift 4.2 migrator.\n";
    OS << "fileprivate func ";
    Info.FuncNameStart = Info.Buffer.size();
    OS << (FromString ? "convertTo" : "convertFrom");
    SmallVector<std::string, 8> Segs;
    StringRef guard = "\tguard let input = input else { return nil }\n";
    switch(Anno) {
    case NodeAnnotation::OptionalArrayMemberUpdate:
      Segs = {"Optional", "Array", (Twine("[") + RawType + "]?").str()};
      Segs.push_back((Twine("[") + NewType +"]?").str());
      Segs.push_back((Twine(guard) + "\treturn input.map { key in " + NewType +"(key) }").str());
      Segs.push_back((Twine(guard) + "\treturn input.map { key in key.rawValue }").str());
      break;
    case NodeAnnotation::OptionalDictionaryKeyUpdate:
      Segs = {"Optional", "Dictionary", (Twine("[") + RawType + ": Any]?").str()};
      Segs.push_back((Twine("[") + NewType +": Any]?").str());
      Segs.push_back((Twine(guard) +
                      "\treturn Dictionary(uniqueKeysWithValues: input.map"
                      " { key, value in (" + NewType + "(rawValue: key), value)})").str());
      Segs.push_back((Twine(guard) +
                      "\treturn Dictionary(uniqueKeysWithValues: input.map"
                      " {key, value in (key.rawValue, value)})").str());
      break;
    case NodeAnnotation::ArrayMemberUpdate:
      Segs = {"", "Array", (Twine("[") + RawType + "]").str()};
      Segs.push_back((Twine("[") + NewType +"]").str());
      Segs.push_back((Twine("\treturn input.map { key in ") + NewType +"(key) }").str());
      Segs.push_back("\treturn input.map { key in key.rawValue }");
      break;
    case NodeAnnotation::DictionaryKeyUpdate:
      Segs = {"", "Dictionary", (Twine("[") + RawType + ": Any]").str()};
      Segs.push_back((Twine("[") + NewType +": Any]").str());
      Segs.push_back((Twine("\treturn Dictionary(uniqueKeysWithValues: input.map"
        " { key, value in (") + NewType + "(rawValue: key), value)})").str());
      Segs.push_back("\treturn Dictionary(uniqueKeysWithValues: input.map"
                     " {key, value in (key.rawValue, value)})");
      break;
    case NodeAnnotation::SimpleStringRepresentableUpdate:
      Segs = {"", "", RawType};
      Segs.push_back(NewType);
      Segs.push_back((Twine("\treturn ") + NewType + "(rawValue: input)").str());
      Segs.push_back("\treturn input.rawValue");
      break;
    case NodeAnnotation::SimpleOptionalStringRepresentableUpdate:
      Segs = {"Optional", "", (Twine(RawType) +"?").str()};
      Segs.push_back((Twine(NewType) +"?").str());
      Segs.push_back((Twine(guard) + "\treturn " + NewType + "(rawValue: input)").str());
      Segs.push_back((Twine(guard) + "\treturn input.rawValue").str());
      break;
    default:
      llvm_unreachable("shouldn't handle this key.");
    }
    assert(Segs.size() == 6);
    OS << Segs[0];
    SmallVector<StringRef, 4> Parts;
    NewType.split(Parts, '.');
    for (auto P: Parts)
      OS << P;
    OS << Segs[1];
    Info.FuncNameEnd = Info.Buffer.size();
    if (FromString) {
      OS << "(_ input: " << Segs[2] << ") -> " << Segs[3] << " {\n";
      OS << Segs[4] << "\n}\n";
    } else {
      OS << "(_ input: " << Segs[3] << ") -> " << Segs[2] << " {\n";
      OS << Segs[5] << "\n}\n";
    }
    return Info;
  }

  void handleStringRepresentableArg(ValueDecl *FD, Expr *Arg, Expr *Call) {
    NodeAnnotation Kind;
    StringRef RawType;
    StringRef NewAttributeType;
    uint8_t ArgIdx;
    for (auto Item: getRelatedDiffItems(FD)) {
      if (auto *CI = dyn_cast<CommonDiffItem>(Item)) {
        if (CI->isStringRepresentableChange()) {
          Kind = CI->DiffKind;
          RawType = CI->LeftComment;
          NewAttributeType = CI->RightComment;
          assert(CI->getChildIndices().size() == 1);
          ArgIdx = CI->getChildIndices().front();
          break;
        }
      }
    }
    if (NewAttributeType.empty())
      return;
    Expr *WrapTarget = Call;
    bool FromString = false;
    if (ArgIdx) {
      ArgIdx --;
      FromString = true;
      auto AllArgs = getCallArgInfo(SM, Arg, LabelRangeEndAt::LabelNameOnly);
      if (AllArgs.size() <= ArgIdx)
        return;
      WrapTarget = AllArgs[ArgIdx].ArgExp;
    }
    assert(WrapTarget);
    insertHelperFunction(Kind, RawType, NewAttributeType, FromString, WrapTarget);
  }

  bool hasRevertRawRepresentableChange(ValueDecl *VD) {
    for (auto Item: getRelatedDiffItems(VD)) {
      if (auto *CI = dyn_cast<CommonDiffItem>(Item)) {
        if (CI->DiffKind ==
              NodeAnnotation::RevertTypeAliasDeclToRawRepresentable)
          return true;
      }
    }
    return false;
  }

  bool handleRevertRawRepresentable(Expr *E) {
    // Change attribute.rawValue to attribute
    if (auto *MRE = dyn_cast<MemberRefExpr>(E)) {
      auto Found = false;
      if (auto *Base = MRE->getBase()) {
        if (hasRevertRawRepresentableChange(Base->getType()->getAnyNominal())) {
          Found = true;
        }
      }
      if (!Found)
        return false;
      auto NL = MRE->getNameLoc().getStartLoc();
      auto DL = MRE->getDotLoc();
      if (NL.isInvalid() || DL.isInvalid())
        return false;
      CharSourceRange Range = Lexer::getCharSourceRangeFromSourceRange(SM, {DL, NL});
      if (Range.str() == ".rawValue") {
        Editor.remove(Range);
        return true;
      }
    }

    // Change attribute(rawValue: "value") to "value"
    // Change attribute("value") to "value"
    if (auto *CE = dyn_cast<CallExpr>(E)) {
      auto Found = false;
      if (auto *CRC = dyn_cast<ConstructorRefCallExpr>(CE->getFn())) {
        if (auto *TE = dyn_cast<TypeExpr>(CRC->getBase())) {
          if (hasRevertRawRepresentableChange(TE->getInstanceType()->getAnyNominal()))
            Found = true;
        }
      }
      if (!Found)
        return false;
      std::vector<CallArgInfo> AllArgs =
        getCallArgInfo(SM, CE->getArg(), LabelRangeEndAt::LabelNameOnly);
      if (AllArgs.size() == 1) {
        auto Label = AllArgs.front().LabelRange.str();
        if (Label == "rawValue" || Label.empty()) {
          Editor.replace(CE->getSourceRange(),
                         Lexer::getCharSourceRangeFromSourceRange(SM,
                           AllArgs.front().ArgExp->getSourceRange()).str());
          return true;
        }
      }
    }
    return false;
  }

  void handleResultTypeChange(ValueDecl *FD, Expr *Call) {
    Optional<NodeAnnotation> ChangeKind;

    // look for related change item for the function decl.
    for (auto Item: getRelatedDiffItems(FD)) {
      if (auto *CI = dyn_cast<CommonDiffItem>(Item)) {
        // check if the function's return type has been changed from nonnull
        // to nullable.
        if (CI->DiffKind == NodeAnnotation::WrapOptional &&
            CI->getChildIndices().size() == 1 &&
            CI->getChildIndices().front() == 0) {
          ChangeKind = NodeAnnotation::WrapOptional;
          break;
        }
      }
    }
    if (!ChangeKind.hasValue())
      return;
    // If a function's return type has been changed from nonnull to nullable,
    // append ! to the original call expression.
    if (*ChangeKind == NodeAnnotation::WrapOptional) {
      Editor.insertAfterToken(Call->getSourceRange().End, "!");
    }
  }

  // If a property has changed from nonnull to nullable, we should add ! to the
  // reference of the property.
  bool handlePropertyTypeChange(Expr *E) {
    if (auto MRE = dyn_cast<MemberRefExpr>(E)) {
      if (auto *VD = MRE->getReferencedDecl().getDecl()) {
        for (auto *I: getRelatedDiffItems(VD)) {
          if (auto *Item = dyn_cast<CommonDiffItem>(I)) {
            if (Item->DiffKind == NodeAnnotation::WrapOptional &&
                Item->NodeKind == SDKNodeKind::DeclVar) {
              Editor.insertAfterToken(E->getEndLoc(), "!");
              return true;
            }
          }
        }
      }
    }
    return false;
  }

  bool walkToExprPre(Expr *E) override {
    if (E->getSourceRange().isInvalid())
      return false;
    if (handleRevertRawRepresentable(E)) {
      // The name may also change, so we should keep visiting.
      return true;
    }
    if (handleQualifiedReplacement(E))
      return false;
    if (handleAssignDestMigration(E))
      return false;
    if (handleAttributeReference(E))
      return false;
    if (handlePropertyTypeChange(E))
      return false;
    if (auto *CE = dyn_cast<CallExpr>(E)) {
      auto Fn = CE->getFn();
      auto Args = CE->getArg();
      switch (Fn->getKind()) {
      case ExprKind::DeclRef: {
        if (auto FD = Fn->getReferencedDecl().getDecl()) {
          handleFuncRename(FD, Fn, Args);
          handleTypeHoist(FD, CE, Args);
          handleSpecialCases(FD, CE, Args);
          handleStringRepresentableArg(FD, Args, CE);
          handleResultTypeChange(FD, CE);
        }
        break;
      }
      case ExprKind::DotSyntaxCall: {
        auto DSC = cast<DotSyntaxCallExpr>(Fn);
        if (auto FD = DSC->getFn()->getReferencedDecl().getDecl()) {
          handleFuncRename(FD, DSC->getFn(), Args);
          handleFunctionCallToPropertyChange(FD, DSC->getFn(), Args);
          handleSpecialCases(FD, CE, Args);
          handleStringRepresentableArg(FD, Args, CE);
          handleResultTypeChange(FD, CE);
        }
        break;
      }
      case ExprKind::ConstructorRefCall: {
        auto CCE = cast<ConstructorRefCallExpr>(Fn);
        if (auto FD = CCE->getFn()->getReferencedDecl().getDecl()) {
          handleFuncRename(FD, CE, Args);
          handleStringRepresentableArg(FD, Args, CE);
          handleResultTypeChange(FD, CE);
        }
        break;
      }
      default:
        break;
      }
    }
    return true;
  }

  static void collectParamters(AbstractFunctionDecl *AFD,
                               SmallVectorImpl<ParamDecl*> &Results) {
    for (auto PD : *AFD->getParameters()) {
      Results.push_back(PD);
    }
  }

  void handleFuncDeclRename(AbstractFunctionDecl *AFD,
                            CharSourceRange NameRange) {
    bool IgnoreBase = false;
    llvm::SmallString<32> Buffer;
    if (auto View = getFuncRename(AFD, Buffer, IgnoreBase)) {
      if (!IgnoreBase)
        Editor.replace(NameRange, View.base());
      unsigned Index = 0;
      SmallVector<ParamDecl*, 4> Params;
      collectParamters(AFD, Params);
      for (auto *PD: Params) {
        if (Index == View.argSize())
          break;
        StringRef NewArg = View.args()[Index++];
        auto ArgLoc = PD->getArgumentNameLoc();

        // Represent empty label with underscore.
        if (NewArg.empty())
          NewArg = "_";

        // If the argument name is not specified, add the argument name before
        // the parameter name.
        if (ArgLoc.isInvalid())
          Editor.insertBefore(PD->getNameLoc(),
                              (llvm::Twine(NewArg) + " ").str());
        else {
          // Otherwise, replace the argument name directly.
          Editor.replaceToken(ArgLoc, NewArg);
        }
      }
    }
  }

  bool typeReplacementMayNeedParens(StringRef Replacement) const {
    return Replacement.contains('&') || Replacement.contains("->");
  }

  void handleOverridingTypeChange(AbstractFunctionDecl *AFD,
                                  CommonDiffItem *DiffItem) {
    assert(AFD);
    assert(DiffItem->isTypeChange());
    ChildIndexFinder Finder(DiffItem->getChildIndices());
    auto Result = Finder.findChild(AFD);
    if (!Result.isValid())
      return;

    switch (DiffItem->DiffKind) {
      case ide::api::NodeAnnotation::WrapOptional:
        if (Result.Suffixable) {
          Editor.insertAfterToken(Result.TokenRange.End, "?");
        } else {
          Editor.insertWrap("(", Result.TokenRange, ")?");
        }
        break;
      case ide::api::NodeAnnotation::WrapImplicitOptional:
        if (Result.Suffixable) {
          Editor.insertAfterToken(Result.TokenRange.End, "!");
        } else {
          Editor.insertWrap("(", Result.TokenRange, (")!"));
        }
        break;
      case ide::api::NodeAnnotation::UnwrapOptional:
        if (Result.Optional)
          Editor.remove(Result.TokenRange.End);
        break;
      case ide::api::NodeAnnotation::ImplicitOptionalToOptional:
        if (Result.Optional)
          Editor.replace(Result.TokenRange.End, "?");
        break;
      case ide::api::NodeAnnotation::TypeRewritten:
        Editor.replace(Result.TokenRange, DiffItem->RightComment);
        if (Result.Suffixed && typeReplacementMayNeedParens(DiffItem->RightComment)) {
          Editor.insertBefore(Result.TokenRange.Start, "(");
          Editor.insertAfterToken(Result.TokenRange.End, ")");
        }
        break;
      default:
        break;
    }
  }

  void handleOverridingPropertyChange(AbstractFunctionDecl *AFD,
                                      CommonDiffItem *DiffItem) {
    assert(AFD);
    assert(DiffItem->isToPropertyChange());
    auto FD = dyn_cast<FuncDecl>(AFD);
    if (!FD)
      return;

    switch (DiffItem->DiffKind) {
    case NodeAnnotation::GetterToProperty: {
      auto FuncLoc = FD->getFuncLoc();
      auto ReturnTyLoc = FD->getBodyResultTypeLoc().getSourceRange().Start;
      auto NameLoc = FD->getNameLoc();
      if (FuncLoc.isInvalid() || ReturnTyLoc.isInvalid() || NameLoc.isInvalid())
        break;

      // Replace "func" with "var"
      Editor.replaceToken(FuncLoc, "var");

      // Replace "() -> " with ": "
      Editor.replace(CharSourceRange(SM, Lexer::getLocForEndOfToken(SM, NameLoc),
        ReturnTyLoc), ": ");

      break;
    }
    case NodeAnnotation::SetterToProperty: {
      // FIXME: we should migrate this case too.
      break;
    }
    default:
      llvm_unreachable("should not be handled here.");
    }
  }

  // When users override a SDK function whose parameter types have been changed,
  // we should introduce a local variable in the body of the function definition
  // to shadow the changed parameter. Also, a proper conversion function should
  // be defined to bridge the parameter to the local variable.
  void handleLocalParameterBridge(AbstractFunctionDecl *AFD,
                                  CommonDiffItem *DiffItem) {
    assert(AFD);
    assert(DiffItem->isStringRepresentableChange());

    // We only handle top-level parameter type change.
    if (DiffItem->getChildIndices().size() != 1)
      return;
    auto Idx = DiffItem->getChildIndices().front();

    // We don't handle return type change.
    if (Idx == 0)
      return;
    Idx --;
    SmallVector<ParamDecl*, 4> Params;
    collectParamters(AFD, Params);
    if (Params.size() <= Idx)
      return;

    // Get the internal name of the changed paramter.
    auto VariableName = Params[Idx]->getParameterName().str();

    // Insert the helper function to convert the type back to raw types.
    auto &Info = insertHelperFunction(DiffItem->DiffKind, DiffItem->LeftComment,
      DiffItem->RightComment, /*From String*/false,
      /*No expression to wrap*/nullptr);

    auto BL = AFD->getBodySourceRange().Start;
    if (BL.isValid()) {
      // Insert the local variable declaration after the opening brace.
      Editor.insertAfterToken(BL,
        (llvm::Twine("\n// Local variable inserted by Swift 4.2 migrator.") +
         "\nlet " + VariableName + " = " + Info.getFuncName() + "(" +
         VariableName + ")\n").str());
    }
  }

  llvm::StringSet<> funcNamesForOverrideRemoval() {
    llvm::StringSet<> Results;
    Results.insert("c:objc(cs)NSObject(im)application:delegateHandlesKey:");
    Results.insert("c:objc(cs)NSObject(im)changeColor:");
    Results.insert("c:objc(cs)NSObject(im)controlTextDidBeginEditing:");
    Results.insert("c:objc(cs)NSObject(im)controlTextDidEndEditing:");
    Results.insert("c:objc(cs)NSObject(im)controlTextDidChange:");
    Results.insert("c:objc(cs)NSObject(im)changeFont:");
    Results.insert("c:objc(cs)NSObject(im)validModesForFontPanel:");
    Results.insert("c:objc(cs)NSObject(im)discardEditing");
    Results.insert("c:objc(cs)NSObject(im)commitEditing");
    Results.insert("c:objc(cs)NSObject(im)commitEditingWithDelegate:didCommitSelector:contextInfo:");
    Results.insert("c:objc(cs)NSObject(im)commitEditingAndReturnError:");
    Results.insert("c:objc(cs)NSObject(im)objectDidBeginEditing:");
    Results.insert("c:objc(cs)NSObject(im)objectDidEndEditing:");
    Results.insert("c:objc(cs)NSObject(im)validateMenuItem:");
    Results.insert("c:objc(cs)NSObject(im)pasteboard:provideDataForType:");
    Results.insert("c:objc(cs)NSObject(im)pasteboardChangedOwner:");
    Results.insert("c:objc(cs)NSObject(im)validateToolbarItem:");
    Results.insert("c:objc(cs)NSObject(im)layer:shouldInheritContentsScale:fromWindow:");
    Results.insert("c:objc(cs)NSObject(im)view:stringForToolTip:point:userData:");
    return Results;
  }

  SourceLoc shouldRemoveOverride(AbstractFunctionDecl *AFD) {
    if (AFD->getKind() != DeclKind::Func)
      return SourceLoc();
    SourceLoc OverrideLoc;

    // Get the location of override keyword.
    if (auto *Override = AFD->getAttrs().getAttribute<OverrideAttr>()) {
      if (Override->getRange().isValid()) {
        OverrideLoc = Override->getLocation();
      }
    }
    if (OverrideLoc.isInvalid())
      return SourceLoc();
    auto *OD = AFD->getOverriddenDecl();
    llvm::SmallString<64> Buffer;
    llvm::raw_svector_ostream OS(Buffer);
    if (swift::ide::printValueDeclUSR(OD, OS))
      return SourceLoc();
    return OverridingRemoveNames.find(OS.str()) == OverridingRemoveNames.end() ?
      SourceLoc() : OverrideLoc;
  }

  struct SuperRemoval: public ASTWalker {
    EditorAdapter &Editor;
    llvm::StringSet<> &USRs;
    SuperRemoval(EditorAdapter &Editor, llvm::StringSet<> &USRs):
      Editor(Editor), USRs(USRs) {}
    bool isSuperExpr(Expr *E) {
      if (E->isImplicit())
	return false;
      // Check if the expression is super.foo().
      if (auto *CE = dyn_cast<CallExpr>(E)) {
        if (auto *DSC = dyn_cast<DotSyntaxCallExpr>(CE->getFn())) {
          if (DSC->getBase()->getKind() != ExprKind::SuperRef)
            return false;
          llvm::SmallString<64> Buffer;
          llvm::raw_svector_ostream OS(Buffer);
          auto *RD = DSC->getFn()->getReferencedDecl().getDecl();
          if (swift::ide::printValueDeclUSR(RD, OS))
            return false;
          return USRs.find(OS.str()) != USRs.end();
        }
      }
      // We should handle try super.foo() too.
      if (auto *TE = dyn_cast<AnyTryExpr>(E)) {
        return isSuperExpr(TE->getSubExpr());
      }
      return false;
    }
    std::pair<bool, Stmt*> walkToStmtPre(Stmt *S) override {
      if (auto *BS = dyn_cast<BraceStmt>(S)) {
	for(auto Ele: BS->getElements()) {
	  if (Ele.is<Expr*>() && isSuperExpr(Ele.get<Expr*>())) {
	    Editor.remove(Ele.getSourceRange());
          }
	}
      }
      // We only handle top-level expressions, so avoid visiting further.
      return {false, S};
    }
  };

  bool walkToDeclPre(Decl *D, CharSourceRange Range) override {
    if (D->isImplicit())
      return true;
    if (auto *AFD = dyn_cast<AbstractFunctionDecl>(D)) {
      handleFuncDeclRename(AFD, Range);
      for (auto *Item: getRelatedDiffItems(AFD)) {
        if (auto *DiffItem = dyn_cast<CommonDiffItem>(Item)) {
          if (DiffItem->isTypeChange())
            handleOverridingTypeChange(AFD, DiffItem);
          else if (DiffItem->isToPropertyChange())
            handleOverridingPropertyChange(AFD, DiffItem);
          else if (DiffItem->isStringRepresentableChange())
            handleLocalParameterBridge(AFD, DiffItem);
        }
      }
      auto OverrideLoc = shouldRemoveOverride(AFD);
      if (OverrideLoc.isValid()) {
        // Remove override keyword.
        Editor.remove(OverrideLoc);
        // Remove super-dot call.
        SuperRemoval Removal(Editor, OverridingRemoveNames);
        D->walk(Removal);
      }
    }

    // Handle property overriding migration.
    if (auto *VD = dyn_cast<VarDecl>(D)) {
      for (auto *Item: getRelatedDiffItems(VD)) {
        if (auto *CD = dyn_cast<CommonDiffItem>(Item)) {
          // If the overriden property has been renamed, we should rename
          // this property decl as well.
          if (CD->isRename() && VD->getNameLoc().isValid()) {
            Editor.replaceToken(VD->getNameLoc(), CD->getNewName());
          }
        }
      }
    }
    return true;
  }
};

} // end anonymous namespace

void migrator::runAPIDiffMigratorPass(EditorAdapter &Editor,
                                      SourceFile *SF,
                                      const MigratorOptions &Opts) {
  APIDiffMigratorPass { Editor, SF, Opts }.run();
}
