//===--- RewriteObjCFoundationAPI.cpp - Foundation API Rewriter -----------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Rewrites legacy method calls to modern syntax.
//
//===----------------------------------------------------------------------===//

#include "clang/Edit/Rewriters.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/ExprCXX.h"
#include "clang/AST/ExprObjC.h"
#include "clang/AST/NSAPI.h"
#include "clang/AST/ParentMap.h"
#include "clang/Edit/Commit.h"
#include "clang/Lex/Lexer.h"

using namespace clang;
using namespace edit;

static bool checkForLiteralCreation(const ObjCMessageExpr *Msg,
                                    IdentifierInfo *&ClassId,
                                    const LangOptions &LangOpts) {
  if (!Msg || Msg->isImplicit() || !Msg->getMethodDecl())
    return false;

  const ObjCInterfaceDecl *Receiver = Msg->getReceiverInterface();
  if (!Receiver)
    return false;
  ClassId = Receiver->getIdentifier();

  if (Msg->getReceiverKind() == ObjCMessageExpr::Class)
    return true;

  // When in ARC mode we also convert "[[.. alloc] init]" messages to literals,
  // since the change from +1 to +0 will be handled fine by ARC.
  if (LangOpts.ObjCAutoRefCount) {
    if (Msg->getReceiverKind() == ObjCMessageExpr::Instance) {
      if (const ObjCMessageExpr *Rec = dyn_cast<ObjCMessageExpr>(
                           Msg->getInstanceReceiver()->IgnoreParenImpCasts())) {
        if (Rec->getMethodFamily() == OMF_alloc)
          return true;
      }
    }
  }

  return false;
}

//===----------------------------------------------------------------------===//
// rewriteObjCRedundantCallWithLiteral.
//===----------------------------------------------------------------------===//

bool edit::rewriteObjCRedundantCallWithLiteral(const ObjCMessageExpr *Msg,
                                              const NSAPI &NS, Commit &commit) {
  IdentifierInfo *II = nullptr;
  if (!checkForLiteralCreation(Msg, II, NS.getASTContext().getLangOpts()))
    return false;
  if (Msg->getNumArgs() != 1)
    return false;

  const Expr *Arg = Msg->getArg(0)->IgnoreParenImpCasts();
  Selector Sel = Msg->getSelector();

  if ((isa<ObjCStringLiteral>(Arg) &&
       NS.getNSClassId(NSAPI::ClassId_NSString) == II &&
       (NS.getNSStringSelector(NSAPI::NSStr_stringWithString) == Sel ||
        NS.getNSStringSelector(NSAPI::NSStr_initWithString) == Sel))   ||

      (isa<ObjCArrayLiteral>(Arg) &&
       NS.getNSClassId(NSAPI::ClassId_NSArray) == II &&
       (NS.getNSArraySelector(NSAPI::NSArr_arrayWithArray) == Sel ||
        NS.getNSArraySelector(NSAPI::NSArr_initWithArray) == Sel))     ||

      (isa<ObjCDictionaryLiteral>(Arg) &&
       NS.getNSClassId(NSAPI::ClassId_NSDictionary) == II &&
       (NS.getNSDictionarySelector(
                              NSAPI::NSDict_dictionaryWithDictionary) == Sel ||
        NS.getNSDictionarySelector(NSAPI::NSDict_initWithDictionary) == Sel))) {
    
    commit.replaceWithInner(Msg->getSourceRange(),
                           Msg->getArg(0)->getSourceRange());
    return true;
  }

  return false;
}

//===----------------------------------------------------------------------===//
// rewriteToObjCSubscriptSyntax.
//===----------------------------------------------------------------------===//

/// \brief Check for classes that accept 'objectForKey:' (or the other selectors
/// that the migrator handles) but return their instances as 'id', resulting
/// in the compiler resolving 'objectForKey:' as the method from NSDictionary.
///
/// When checking if we can convert to subscripting syntax, check whether
/// the receiver is a result of a class method from a hardcoded list of
/// such classes. In such a case return the specific class as the interface
/// of the receiver.
///
/// FIXME: Remove this when these classes start using 'instancetype'.
static const ObjCInterfaceDecl *
maybeAdjustInterfaceForSubscriptingCheck(const ObjCInterfaceDecl *IFace,
                                         const Expr *Receiver,
                                         ASTContext &Ctx) {
  assert(IFace && Receiver);

  // If the receiver has type 'id'...
  if (!Ctx.isObjCIdType(Receiver->getType().getUnqualifiedType()))
    return IFace;

  const ObjCMessageExpr *
    InnerMsg = dyn_cast<ObjCMessageExpr>(Receiver->IgnoreParenCasts());
  if (!InnerMsg)
    return IFace;

  QualType ClassRec;
  switch (InnerMsg->getReceiverKind()) {
  case ObjCMessageExpr::Instance:
  case ObjCMessageExpr::SuperInstance:
    return IFace;

  case ObjCMessageExpr::Class:
    ClassRec = InnerMsg->getClassReceiver();
    break;
  case ObjCMessageExpr::SuperClass:
    ClassRec = InnerMsg->getSuperType();
    break;
  }

  if (ClassRec.isNull())
    return IFace;

  // ...and it is the result of a class message...

  const ObjCObjectType *ObjTy = ClassRec->getAs<ObjCObjectType>();
  if (!ObjTy)
    return IFace;
  const ObjCInterfaceDecl *OID = ObjTy->getInterface();

  // ...and the receiving class is NSMapTable or NSLocale, return that
  // class as the receiving interface.
  if (OID->getName() == "NSMapTable" ||
      OID->getName() == "NSLocale")
    return OID;

  return IFace;
}

static bool canRewriteToSubscriptSyntax(const ObjCInterfaceDecl *&IFace,
                                        const ObjCMessageExpr *Msg,
                                        ASTContext &Ctx,
                                        Selector subscriptSel) {
  const Expr *Rec = Msg->getInstanceReceiver();
  if (!Rec)
    return false;
  IFace = maybeAdjustInterfaceForSubscriptingCheck(IFace, Rec, Ctx);

  if (const ObjCMethodDecl *MD = IFace->lookupInstanceMethod(subscriptSel)) {
    if (!MD->isUnavailable())
      return true;
  }
  return false;
}

static bool subscriptOperatorNeedsParens(const Expr *FullExpr);

static void maybePutParensOnReceiver(const Expr *Receiver, Commit &commit) {
  if (subscriptOperatorNeedsParens(Receiver)) {
    SourceRange RecRange = Receiver->getSourceRange();
    commit.insertWrap("(", RecRange, ")");
  }
}

static bool rewriteToSubscriptGetCommon(const ObjCMessageExpr *Msg,
                                        Commit &commit) {
  if (Msg->getNumArgs() != 1)
    return false;
  const Expr *Rec = Msg->getInstanceReceiver();
  if (!Rec)
    return false;

  SourceRange MsgRange = Msg->getSourceRange();
  SourceRange RecRange = Rec->getSourceRange();
  SourceRange ArgRange = Msg->getArg(0)->getSourceRange();

  commit.replaceWithInner(CharSourceRange::getCharRange(MsgRange.getBegin(),
                                                       ArgRange.getBegin()),
                         CharSourceRange::getTokenRange(RecRange));
  commit.replaceWithInner(SourceRange(ArgRange.getBegin(), MsgRange.getEnd()),
                         ArgRange);
  commit.insertWrap("[", ArgRange, "]");
  maybePutParensOnReceiver(Rec, commit);
  return true;
}

static bool rewriteToArraySubscriptGet(const ObjCInterfaceDecl *IFace,
                                       const ObjCMessageExpr *Msg,
                                       const NSAPI &NS,
                                       Commit &commit) {
  if (!canRewriteToSubscriptSyntax(IFace, Msg, NS.getASTContext(),
                                   NS.getObjectAtIndexedSubscriptSelector()))
    return false;
  return rewriteToSubscriptGetCommon(Msg, commit);
}

static bool rewriteToDictionarySubscriptGet(const ObjCInterfaceDecl *IFace,
                                            const ObjCMessageExpr *Msg,
                                            const NSAPI &NS,
                                            Commit &commit) {
  if (!canRewriteToSubscriptSyntax(IFace, Msg, NS.getASTContext(),
                                  NS.getObjectForKeyedSubscriptSelector()))
    return false;
  return rewriteToSubscriptGetCommon(Msg, commit);
}

static bool rewriteToArraySubscriptSet(const ObjCInterfaceDecl *IFace,
                                       const ObjCMessageExpr *Msg,
                                       const NSAPI &NS,
                                       Commit &commit) {
  if (!canRewriteToSubscriptSyntax(IFace, Msg, NS.getASTContext(),
                                   NS.getSetObjectAtIndexedSubscriptSelector()))
    return false;

  if (Msg->getNumArgs() != 2)
    return false;
  const Expr *Rec = Msg->getInstanceReceiver();
  if (!Rec)
    return false;

  SourceRange MsgRange = Msg->getSourceRange();
  SourceRange RecRange = Rec->getSourceRange();
  SourceRange Arg0Range = Msg->getArg(0)->getSourceRange();
  SourceRange Arg1Range = Msg->getArg(1)->getSourceRange();

  commit.replaceWithInner(CharSourceRange::getCharRange(MsgRange.getBegin(),
                                                       Arg0Range.getBegin()),
                         CharSourceRange::getTokenRange(RecRange));
  commit.replaceWithInner(CharSourceRange::getCharRange(Arg0Range.getBegin(),
                                                       Arg1Range.getBegin()),
                         CharSourceRange::getTokenRange(Arg0Range));
  commit.replaceWithInner(SourceRange(Arg1Range.getBegin(), MsgRange.getEnd()),
                         Arg1Range);
  commit.insertWrap("[", CharSourceRange::getCharRange(Arg0Range.getBegin(),
                                                       Arg1Range.getBegin()),
                    "] = ");
  maybePutParensOnReceiver(Rec, commit);
  return true;
}

static bool rewriteToDictionarySubscriptSet(const ObjCInterfaceDecl *IFace,
                                            const ObjCMessageExpr *Msg,
                                            const NSAPI &NS,
                                            Commit &commit) {
  if (!canRewriteToSubscriptSyntax(IFace, Msg, NS.getASTContext(),
                                   NS.getSetObjectForKeyedSubscriptSelector()))
    return false;

  if (Msg->getNumArgs() != 2)
    return false;
  const Expr *Rec = Msg->getInstanceReceiver();
  if (!Rec)
    return false;

  SourceRange MsgRange = Msg->getSourceRange();
  SourceRange RecRange = Rec->getSourceRange();
  SourceRange Arg0Range = Msg->getArg(0)->getSourceRange();
  SourceRange Arg1Range = Msg->getArg(1)->getSourceRange();

  SourceLocation LocBeforeVal = Arg0Range.getBegin();
  commit.insertBefore(LocBeforeVal, "] = ");
  commit.insertFromRange(LocBeforeVal, Arg1Range, /*afterToken=*/false,
                         /*beforePreviousInsertions=*/true);
  commit.insertBefore(LocBeforeVal, "[");
  commit.replaceWithInner(CharSourceRange::getCharRange(MsgRange.getBegin(),
                                                       Arg0Range.getBegin()),
                         CharSourceRange::getTokenRange(RecRange));
  commit.replaceWithInner(SourceRange(Arg0Range.getBegin(), MsgRange.getEnd()),
                         Arg0Range);
  maybePutParensOnReceiver(Rec, commit);
  return true;
}

bool edit::rewriteToObjCSubscriptSyntax(const ObjCMessageExpr *Msg,
                                        const NSAPI &NS, Commit &commit) {
  if (!Msg || Msg->isImplicit() ||
      Msg->getReceiverKind() != ObjCMessageExpr::Instance)
    return false;
  const ObjCMethodDecl *Method = Msg->getMethodDecl();
  if (!Method)
    return false;

  const ObjCInterfaceDecl *IFace =
      NS.getASTContext().getObjContainingInterface(Method);
  if (!IFace)
    return false;
  Selector Sel = Msg->getSelector();

  if (Sel == NS.getNSArraySelector(NSAPI::NSArr_objectAtIndex))
    return rewriteToArraySubscriptGet(IFace, Msg, NS, commit);

  if (Sel == NS.getNSDictionarySelector(NSAPI::NSDict_objectForKey))
    return rewriteToDictionarySubscriptGet(IFace, Msg, NS, commit);

  if (Msg->getNumArgs() != 2)
    return false;

  if (Sel == NS.getNSArraySelector(NSAPI::NSMutableArr_replaceObjectAtIndex))
    return rewriteToArraySubscriptSet(IFace, Msg, NS, commit);

  if (Sel == NS.getNSDictionarySelector(NSAPI::NSMutableDict_setObjectForKey))
    return rewriteToDictionarySubscriptSet(IFace, Msg, NS, commit);

  return false;
}

//===----------------------------------------------------------------------===//
// rewriteToObjCLiteralSyntax.
//===----------------------------------------------------------------------===//

static bool rewriteToArrayLiteral(const ObjCMessageExpr *Msg,
                                  const NSAPI &NS, Commit &commit,
                                  const ParentMap *PMap);
static bool rewriteToDictionaryLiteral(const ObjCMessageExpr *Msg,
                                  const NSAPI &NS, Commit &commit);
static bool rewriteToNumberLiteral(const ObjCMessageExpr *Msg,
                                  const NSAPI &NS, Commit &commit);
static bool rewriteToNumericBoxedExpression(const ObjCMessageExpr *Msg,
                                            const NSAPI &NS, Commit &commit);
static bool rewriteToStringBoxedExpression(const ObjCMessageExpr *Msg,
                                           const NSAPI &NS, Commit &commit);

bool edit::rewriteToObjCLiteralSyntax(const ObjCMessageExpr *Msg,
                                      const NSAPI &NS, Commit &commit,
                                      const ParentMap *PMap) {
  IdentifierInfo *II = nullptr;
  if (!checkForLiteralCreation(Msg, II, NS.getASTContext().getLangOpts()))
    return false;

  if (II == NS.getNSClassId(NSAPI::ClassId_NSArray))
    return rewriteToArrayLiteral(Msg, NS, commit, PMap);
  if (II == NS.getNSClassId(NSAPI::ClassId_NSDictionary))
    return rewriteToDictionaryLiteral(Msg, NS, commit);
  if (II == NS.getNSClassId(NSAPI::ClassId_NSNumber))
    return rewriteToNumberLiteral(Msg, NS, commit);
  if (II == NS.getNSClassId(NSAPI::ClassId_NSString))
    return rewriteToStringBoxedExpression(Msg, NS, commit);

  return false;
}

/// \brief Returns true if the immediate message arguments of \c Msg should not
/// be rewritten because it will interfere with the rewrite of the parent
/// message expression. e.g.
/// \code
///   [NSDictionary dictionaryWithObjects:
///                                 [NSArray arrayWithObjects:@"1", @"2", nil]
///                         forKeys:[NSArray arrayWithObjects:@"A", @"B", nil]];
/// \endcode
/// It will return true for this because we are going to rewrite this directly
/// to a dictionary literal without any array literals.
static bool shouldNotRewriteImmediateMessageArgs(const ObjCMessageExpr *Msg,
                                                 const NSAPI &NS);

//===----------------------------------------------------------------------===//
// rewriteToArrayLiteral.
//===----------------------------------------------------------------------===//

/// \brief Adds an explicit cast to 'id' if the type is not objc object.
static void objectifyExpr(const Expr *E, Commit &commit);

static bool rewriteToArrayLiteral(const ObjCMessageExpr *Msg,
                                  const NSAPI &NS, Commit &commit,
                                  const ParentMap *PMap) {
  if (PMap) {
    const ObjCMessageExpr *ParentMsg =
        dyn_cast_or_null<ObjCMessageExpr>(PMap->getParentIgnoreParenCasts(Msg));
    if (shouldNotRewriteImmediateMessageArgs(ParentMsg, NS))
      return false;
  }

  Selector Sel = Msg->getSelector();
  SourceRange MsgRange = Msg->getSourceRange();

  if (Sel == NS.getNSArraySelector(NSAPI::NSArr_array)) {
    if (Msg->getNumArgs() != 0)
      return false;
    commit.replace(MsgRange, "@[]");
    return true;
  }

  if (Sel == NS.getNSArraySelector(NSAPI::NSArr_arrayWithObject)) {
    if (Msg->getNumArgs() != 1)
      return false;
    objectifyExpr(Msg->getArg(0), commit);
    SourceRange ArgRange = Msg->getArg(0)->getSourceRange();
    commit.replaceWithInner(MsgRange, ArgRange);
    commit.insertWrap("@[", ArgRange, "]");
    return true;
  }

  if (Sel == NS.getNSArraySelector(NSAPI::NSArr_arrayWithObjects) ||
      Sel == NS.getNSArraySelector(NSAPI::NSArr_initWithObjects)) {
    if (Msg->getNumArgs() == 0)
      return false;
    const Expr *SentinelExpr = Msg->getArg(Msg->getNumArgs() - 1);
    if (!NS.getASTContext().isSentinelNullExpr(SentinelExpr))
      return false;

    for (unsigned i = 0, e = Msg->getNumArgs() - 1; i != e; ++i)
      objectifyExpr(Msg->getArg(i), commit);

    if (Msg->getNumArgs() == 1) {
      commit.replace(MsgRange, "@[]");
      return true;
    }
    SourceRange ArgRange(Msg->getArg(0)->getLocStart(),
                         Msg->getArg(Msg->getNumArgs()-2)->getLocEnd());
    commit.replaceWithInner(MsgRange, ArgRange);
    commit.insertWrap("@[", ArgRange, "]");
    return true;
  }

  return false;
}

//===----------------------------------------------------------------------===//
// rewriteToDictionaryLiteral.
//===----------------------------------------------------------------------===//

/// \brief If \c Msg is an NSArray creation message or literal, this gets the
/// objects that were used to create it.
/// \returns true if it is an NSArray and we got objects, or false otherwise.
static bool getNSArrayObjects(const Expr *E, const NSAPI &NS,
                              SmallVectorImpl<const Expr *> &Objs) {
  if (!E)
    return false;

  E = E->IgnoreParenCasts();
  if (!E)
    return false;

  if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E)) {
    IdentifierInfo *Cls = nullptr;
    if (!checkForLiteralCreation(Msg, Cls, NS.getASTContext().getLangOpts()))
      return false;

    if (Cls != NS.getNSClassId(NSAPI::ClassId_NSArray))
      return false;

    Selector Sel = Msg->getSelector();
    if (Sel == NS.getNSArraySelector(NSAPI::NSArr_array))
      return true; // empty array.

    if (Sel == NS.getNSArraySelector(NSAPI::NSArr_arrayWithObject)) {
      if (Msg->getNumArgs() != 1)
        return false;
      Objs.push_back(Msg->getArg(0));
      return true;
    }

    if (Sel == NS.getNSArraySelector(NSAPI::NSArr_arrayWithObjects) ||
        Sel == NS.getNSArraySelector(NSAPI::NSArr_initWithObjects)) {
      if (Msg->getNumArgs() == 0)
        return false;
      const Expr *SentinelExpr = Msg->getArg(Msg->getNumArgs() - 1);
      if (!NS.getASTContext().isSentinelNullExpr(SentinelExpr))
        return false;

      for (unsigned i = 0, e = Msg->getNumArgs() - 1; i != e; ++i)
        Objs.push_back(Msg->getArg(i));
      return true;
    }

  } else if (const ObjCArrayLiteral *ArrLit = dyn_cast<ObjCArrayLiteral>(E)) {
    for (unsigned i = 0, e = ArrLit->getNumElements(); i != e; ++i)
      Objs.push_back(ArrLit->getElement(i));
    return true;
  }

  return false;
}

static bool rewriteToDictionaryLiteral(const ObjCMessageExpr *Msg,
                                       const NSAPI &NS, Commit &commit) {
  Selector Sel = Msg->getSelector();
  SourceRange MsgRange = Msg->getSourceRange();

  if (Sel == NS.getNSDictionarySelector(NSAPI::NSDict_dictionary)) {
    if (Msg->getNumArgs() != 0)
      return false;
    commit.replace(MsgRange, "@{}");
    return true;
  }

  if (Sel == NS.getNSDictionarySelector(
                                    NSAPI::NSDict_dictionaryWithObjectForKey)) {
    if (Msg->getNumArgs() != 2)
      return false;

    objectifyExpr(Msg->getArg(0), commit);
    objectifyExpr(Msg->getArg(1), commit);

    SourceRange ValRange = Msg->getArg(0)->getSourceRange();
    SourceRange KeyRange = Msg->getArg(1)->getSourceRange();
    // Insert key before the value.
    commit.insertBefore(ValRange.getBegin(), ": ");
    commit.insertFromRange(ValRange.getBegin(),
                           CharSourceRange::getTokenRange(KeyRange),
                       /*afterToken=*/false, /*beforePreviousInsertions=*/true);
    commit.insertBefore(ValRange.getBegin(), "@{");
    commit.insertAfterToken(ValRange.getEnd(), "}");
    commit.replaceWithInner(MsgRange, ValRange);
    return true;
  }

  if (Sel == NS.getNSDictionarySelector(
                                  NSAPI::NSDict_dictionaryWithObjectsAndKeys) ||
      Sel == NS.getNSDictionarySelector(NSAPI::NSDict_initWithObjectsAndKeys)) {
    if (Msg->getNumArgs() % 2 != 1)
      return false;
    unsigned SentinelIdx = Msg->getNumArgs() - 1;
    const Expr *SentinelExpr = Msg->getArg(SentinelIdx);
    if (!NS.getASTContext().isSentinelNullExpr(SentinelExpr))
      return false;

    if (Msg->getNumArgs() == 1) {
      commit.replace(MsgRange, "@{}");
      return true;
    }

    for (unsigned i = 0; i < SentinelIdx; i += 2) {
      objectifyExpr(Msg->getArg(i), commit);
      objectifyExpr(Msg->getArg(i+1), commit);

      SourceRange ValRange = Msg->getArg(i)->getSourceRange();
      SourceRange KeyRange = Msg->getArg(i+1)->getSourceRange();
      // Insert value after key.
      commit.insertAfterToken(KeyRange.getEnd(), ": ");
      commit.insertFromRange(KeyRange.getEnd(), ValRange, /*afterToken=*/true);
      commit.remove(CharSourceRange::getCharRange(ValRange.getBegin(),
                                                  KeyRange.getBegin()));
    }
    // Range of arguments up until and including the last key.
    // The sentinel and first value are cut off, the value will move after the
    // key.
    SourceRange ArgRange(Msg->getArg(1)->getLocStart(),
                         Msg->getArg(SentinelIdx-1)->getLocEnd());
    commit.insertWrap("@{", ArgRange, "}");
    commit.replaceWithInner(MsgRange, ArgRange);
    return true;
  }

  if (Sel == NS.getNSDictionarySelector(
                                  NSAPI::NSDict_dictionaryWithObjectsForKeys) ||
      Sel == NS.getNSDictionarySelector(NSAPI::NSDict_initWithObjectsForKeys)) {
    if (Msg->getNumArgs() != 2)
      return false;

    SmallVector<const Expr *, 8> Vals;
    if (!getNSArrayObjects(Msg->getArg(0), NS, Vals))
      return false;

    SmallVector<const Expr *, 8> Keys;
    if (!getNSArrayObjects(Msg->getArg(1), NS, Keys))
      return false;

    if (Vals.size() != Keys.size())
      return false;

    if (Vals.empty()) {
      commit.replace(MsgRange, "@{}");
      return true;
    }

    for (unsigned i = 0, n = Vals.size(); i < n; ++i) {
      objectifyExpr(Vals[i], commit);
      objectifyExpr(Keys[i], commit);

      SourceRange ValRange = Vals[i]->getSourceRange();
      SourceRange KeyRange = Keys[i]->getSourceRange();
      // Insert value after key.
      commit.insertAfterToken(KeyRange.getEnd(), ": ");
      commit.insertFromRange(KeyRange.getEnd(), ValRange, /*afterToken=*/true);
    }
    // Range of arguments up until and including the last key.
    // The first value is cut off, the value will move after the key.
    SourceRange ArgRange(Keys.front()->getLocStart(),
                         Keys.back()->getLocEnd());
    commit.insertWrap("@{", ArgRange, "}");
    commit.replaceWithInner(MsgRange, ArgRange);
    return true;
  }

  return false;
}

static bool shouldNotRewriteImmediateMessageArgs(const ObjCMessageExpr *Msg,
                                                 const NSAPI &NS) {
  if (!Msg)
    return false;

  IdentifierInfo *II = nullptr;
  if (!checkForLiteralCreation(Msg, II, NS.getASTContext().getLangOpts()))
    return false;

  if (II != NS.getNSClassId(NSAPI::ClassId_NSDictionary))
    return false;

  Selector Sel = Msg->getSelector();
  if (Sel == NS.getNSDictionarySelector(
                                  NSAPI::NSDict_dictionaryWithObjectsForKeys) ||
      Sel == NS.getNSDictionarySelector(NSAPI::NSDict_initWithObjectsForKeys)) {
    if (Msg->getNumArgs() != 2)
      return false;

    SmallVector<const Expr *, 8> Vals;
    if (!getNSArrayObjects(Msg->getArg(0), NS, Vals))
      return false;

    SmallVector<const Expr *, 8> Keys;
    if (!getNSArrayObjects(Msg->getArg(1), NS, Keys))
      return false;

    if (Vals.size() != Keys.size())
      return false;

    return true;
  }

  return false;
}

//===----------------------------------------------------------------------===//
// rewriteToNumberLiteral.
//===----------------------------------------------------------------------===//

static bool rewriteToCharLiteral(const ObjCMessageExpr *Msg,
                                   const CharacterLiteral *Arg,
                                   const NSAPI &NS, Commit &commit) {
  if (Arg->getKind() != CharacterLiteral::Ascii)
    return false;
  if (NS.isNSNumberLiteralSelector(NSAPI::NSNumberWithChar,
                                   Msg->getSelector())) {
    SourceRange ArgRange = Arg->getSourceRange();
    commit.replaceWithInner(Msg->getSourceRange(), ArgRange);
    commit.insert(ArgRange.getBegin(), "@");
    return true;
  }

  return rewriteToNumericBoxedExpression(Msg, NS, commit);
}

static bool rewriteToBoolLiteral(const ObjCMessageExpr *Msg,
                                   const Expr *Arg,
                                   const NSAPI &NS, Commit &commit) {
  if (NS.isNSNumberLiteralSelector(NSAPI::NSNumberWithBool,
                                   Msg->getSelector())) {
    SourceRange ArgRange = Arg->getSourceRange();
    commit.replaceWithInner(Msg->getSourceRange(), ArgRange);
    commit.insert(ArgRange.getBegin(), "@");
    return true;
  }

  return rewriteToNumericBoxedExpression(Msg, NS, commit);
}

namespace {

struct LiteralInfo {
  bool Hex, Octal;
  StringRef U, F, L, LL;
  CharSourceRange WithoutSuffRange;
};

}

static bool getLiteralInfo(SourceRange literalRange,
                           bool isFloat, bool isIntZero,
                          ASTContext &Ctx, LiteralInfo &Info) {
  if (literalRange.getBegin().isMacroID() ||
      literalRange.getEnd().isMacroID())
    return false;
  StringRef text = Lexer::getSourceText(
                                  CharSourceRange::getTokenRange(literalRange),
                                  Ctx.getSourceManager(), Ctx.getLangOpts());
  if (text.empty())
    return false;

  Optional<bool> UpperU, UpperL;
  bool UpperF = false;

  struct Suff {
    static bool has(StringRef suff, StringRef &text) {
      if (text.endswith(suff)) {
        text = text.substr(0, text.size()-suff.size());
        return true;
      }
      return false;
    }
  };

  while (1) {
    if (Suff::has("u", text)) {
      UpperU = false;
    } else if (Suff::has("U", text)) {
      UpperU = true;
    } else if (Suff::has("ll", text)) {
      UpperL = false;
    } else if (Suff::has("LL", text)) {
      UpperL = true;
    } else if (Suff::has("l", text)) {
      UpperL = false;
    } else if (Suff::has("L", text)) {
      UpperL = true;
    } else if (isFloat && Suff::has("f", text)) {
      UpperF = false;
    } else if (isFloat && Suff::has("F", text)) {
      UpperF = true;
    } else
      break;
  }
  
  if (!UpperU.hasValue() && !UpperL.hasValue())
    UpperU = UpperL = true;
  else if (UpperU.hasValue() && !UpperL.hasValue())
    UpperL = UpperU;
  else if (UpperL.hasValue() && !UpperU.hasValue())
    UpperU = UpperL;

  Info.U = *UpperU ? "U" : "u";
  Info.L = *UpperL ? "L" : "l";
  Info.LL = *UpperL ? "LL" : "ll";
  Info.F = UpperF ? "F" : "f";
  
  Info.Hex = Info.Octal = false;
  if (text.startswith("0x"))
    Info.Hex = true;
  else if (!isFloat && !isIntZero && text.startswith("0"))
    Info.Octal = true;

  SourceLocation B = literalRange.getBegin();
  Info.WithoutSuffRange =
      CharSourceRange::getCharRange(B, B.getLocWithOffset(text.size()));
  return true;
}

static bool rewriteToNumberLiteral(const ObjCMessageExpr *Msg,
                                   const NSAPI &NS, Commit &commit) {
  if (Msg->getNumArgs() != 1)
    return false;

  const Expr *Arg = Msg->getArg(0)->IgnoreParenImpCasts();
  if (const CharacterLiteral *CharE = dyn_cast<CharacterLiteral>(Arg))
    return rewriteToCharLiteral(Msg, CharE, NS, commit);
  if (const ObjCBoolLiteralExpr *BE = dyn_cast<ObjCBoolLiteralExpr>(Arg))
    return rewriteToBoolLiteral(Msg, BE, NS, commit);
  if (const CXXBoolLiteralExpr *BE = dyn_cast<CXXBoolLiteralExpr>(Arg))
    return rewriteToBoolLiteral(Msg, BE, NS, commit);

  const Expr *literalE = Arg;
  if (const UnaryOperator *UOE = dyn_cast<UnaryOperator>(literalE)) {
    if (UOE->getOpcode() == UO_Plus || UOE->getOpcode() == UO_Minus)
      literalE = UOE->getSubExpr();
  }

  // Only integer and floating literals, otherwise try to rewrite to boxed
  // expression.
  if (!isa<IntegerLiteral>(literalE) && !isa<FloatingLiteral>(literalE))
    return rewriteToNumericBoxedExpression(Msg, NS, commit);

  ASTContext &Ctx = NS.getASTContext();
  Selector Sel = Msg->getSelector();
  Optional<NSAPI::NSNumberLiteralMethodKind>
    MKOpt = NS.getNSNumberLiteralMethodKind(Sel);
  if (!MKOpt)
    return false;
  NSAPI::NSNumberLiteralMethodKind MK = *MKOpt;

  bool CallIsUnsigned = false, CallIsLong = false, CallIsLongLong = false;
  bool CallIsFloating = false, CallIsDouble = false;

  switch (MK) {
  // We cannot have these calls with int/float literals.
  case NSAPI::NSNumberWithChar:
  case NSAPI::NSNumberWithUnsignedChar:
  case NSAPI::NSNumberWithShort:
  case NSAPI::NSNumberWithUnsignedShort:
  case NSAPI::NSNumberWithBool:
    return rewriteToNumericBoxedExpression(Msg, NS, commit);

  case NSAPI::NSNumberWithUnsignedInt:
  case NSAPI::NSNumberWithUnsignedInteger:
    CallIsUnsigned = true;
  case NSAPI::NSNumberWithInt:
  case NSAPI::NSNumberWithInteger:
    break;

  case NSAPI::NSNumberWithUnsignedLong:
    CallIsUnsigned = true;
  case NSAPI::NSNumberWithLong:
    CallIsLong = true;
    break;

  case NSAPI::NSNumberWithUnsignedLongLong:
    CallIsUnsigned = true;
  case NSAPI::NSNumberWithLongLong:
    CallIsLongLong = true;
    break;

  case NSAPI::NSNumberWithDouble:
    CallIsDouble = true;
  case NSAPI::NSNumberWithFloat:
    CallIsFloating = true;
    break;
  }

  SourceRange ArgRange = Arg->getSourceRange();
  QualType ArgTy = Arg->getType();
  QualType CallTy = Msg->getArg(0)->getType();

  // Check for the easy case, the literal maps directly to the call.
  if (Ctx.hasSameType(ArgTy, CallTy)) {
    commit.replaceWithInner(Msg->getSourceRange(), ArgRange);
    commit.insert(ArgRange.getBegin(), "@");
    return true;
  }

  // We will need to modify the literal suffix to get the same type as the call.
  // Try with boxed expression if it came from a macro.
  if (ArgRange.getBegin().isMacroID())
    return rewriteToNumericBoxedExpression(Msg, NS, commit);

  bool LitIsFloat = ArgTy->isFloatingType();
  // For a float passed to integer call, don't try rewriting to objc literal.
  // It is difficult and a very uncommon case anyway.
  // But try with boxed expression.
  if (LitIsFloat && !CallIsFloating)
    return rewriteToNumericBoxedExpression(Msg, NS, commit);

  // Try to modify the literal make it the same type as the method call.
  // -Modify the suffix, and/or
  // -Change integer to float
  
  LiteralInfo LitInfo;
  bool isIntZero = false;
  if (const IntegerLiteral *IntE = dyn_cast<IntegerLiteral>(literalE))
    isIntZero = !IntE->getValue().getBoolValue();
  if (!getLiteralInfo(ArgRange, LitIsFloat, isIntZero, Ctx, LitInfo))
    return rewriteToNumericBoxedExpression(Msg, NS, commit);

  // Not easy to do int -> float with hex/octal and uncommon anyway.
  if (!LitIsFloat && CallIsFloating && (LitInfo.Hex || LitInfo.Octal))
    return rewriteToNumericBoxedExpression(Msg, NS, commit);
  
  SourceLocation LitB = LitInfo.WithoutSuffRange.getBegin();
  SourceLocation LitE = LitInfo.WithoutSuffRange.getEnd();

  commit.replaceWithInner(CharSourceRange::getTokenRange(Msg->getSourceRange()),
                         LitInfo.WithoutSuffRange);
  commit.insert(LitB, "@");

  if (!LitIsFloat && CallIsFloating)
    commit.insert(LitE, ".0");

  if (CallIsFloating) {
    if (!CallIsDouble)
      commit.insert(LitE, LitInfo.F);
  } else {
    if (CallIsUnsigned)
      commit.insert(LitE, LitInfo.U);
  
    if (CallIsLong)
      commit.insert(LitE, LitInfo.L);
    else if (CallIsLongLong)
      commit.insert(LitE, LitInfo.LL);
  }
  return true;
}

// FIXME: Make determination of operator precedence more general and
// make it broadly available.
static bool subscriptOperatorNeedsParens(const Expr *FullExpr) {
  const Expr* Expr = FullExpr->IgnoreImpCasts();
  if (isa<ArraySubscriptExpr>(Expr) ||
      isa<CallExpr>(Expr) ||
      isa<DeclRefExpr>(Expr) ||
      isa<CXXNamedCastExpr>(Expr) ||
      isa<CXXConstructExpr>(Expr) ||
      isa<CXXThisExpr>(Expr) ||
      isa<CXXTypeidExpr>(Expr) ||
      isa<CXXUnresolvedConstructExpr>(Expr) ||
      isa<ObjCMessageExpr>(Expr) ||
      isa<ObjCPropertyRefExpr>(Expr) ||
      isa<ObjCProtocolExpr>(Expr) ||
      isa<MemberExpr>(Expr) ||
      isa<ObjCIvarRefExpr>(Expr) ||
      isa<ParenExpr>(FullExpr) ||
      isa<ParenListExpr>(Expr) ||
      isa<SizeOfPackExpr>(Expr))
    return false;

  return true;
}
static bool castOperatorNeedsParens(const Expr *FullExpr) {
  const Expr* Expr = FullExpr->IgnoreImpCasts();
  if (isa<ArraySubscriptExpr>(Expr) ||
      isa<CallExpr>(Expr) ||
      isa<DeclRefExpr>(Expr) ||
      isa<CastExpr>(Expr) ||
      isa<CXXNewExpr>(Expr) ||
      isa<CXXConstructExpr>(Expr) ||
      isa<CXXDeleteExpr>(Expr) ||
      isa<CXXNoexceptExpr>(Expr) ||
      isa<CXXPseudoDestructorExpr>(Expr) ||
      isa<CXXScalarValueInitExpr>(Expr) ||
      isa<CXXThisExpr>(Expr) ||
      isa<CXXTypeidExpr>(Expr) ||
      isa<CXXUnresolvedConstructExpr>(Expr) ||
      isa<ObjCMessageExpr>(Expr) ||
      isa<ObjCPropertyRefExpr>(Expr) ||
      isa<ObjCProtocolExpr>(Expr) ||
      isa<MemberExpr>(Expr) ||
      isa<ObjCIvarRefExpr>(Expr) ||
      isa<ParenExpr>(FullExpr) ||
      isa<ParenListExpr>(Expr) ||
      isa<SizeOfPackExpr>(Expr) ||
      isa<UnaryOperator>(Expr))
    return false;

  return true;
}

static void objectifyExpr(const Expr *E, Commit &commit) {
  if (!E) return;

  QualType T = E->getType();
  if (T->isObjCObjectPointerType()) {
    if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(E)) {
      if (ICE->getCastKind() != CK_CPointerToObjCPointerCast)
        return;
    } else {
      return;
    }
  } else if (!T->isPointerType()) {
    return;
  }

  SourceRange Range = E->getSourceRange();
  if (castOperatorNeedsParens(E))
    commit.insertWrap("(", Range, ")");
  commit.insertBefore(Range.getBegin(), "(id)");
}

//===----------------------------------------------------------------------===//
// rewriteToNumericBoxedExpression.
//===----------------------------------------------------------------------===//

static bool isEnumConstant(const Expr *E) {
  if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E->IgnoreParenImpCasts()))
    if (const ValueDecl *VD = DRE->getDecl())
      return isa<EnumConstantDecl>(VD);

  return false;
}

static bool rewriteToNumericBoxedExpression(const ObjCMessageExpr *Msg,
                                            const NSAPI &NS, Commit &commit) {
  if (Msg->getNumArgs() != 1)
    return false;

  const Expr *Arg = Msg->getArg(0);
  if (Arg->isTypeDependent())
    return false;

  ASTContext &Ctx = NS.getASTContext();
  Selector Sel = Msg->getSelector();
  Optional<NSAPI::NSNumberLiteralMethodKind>
    MKOpt = NS.getNSNumberLiteralMethodKind(Sel);
  if (!MKOpt)
    return false;
  NSAPI::NSNumberLiteralMethodKind MK = *MKOpt;

  const Expr *OrigArg = Arg->IgnoreImpCasts();
  QualType FinalTy = Arg->getType();
  QualType OrigTy = OrigArg->getType();
  uint64_t FinalTySize = Ctx.getTypeSize(FinalTy);
  uint64_t OrigTySize = Ctx.getTypeSize(OrigTy);

  bool isTruncated = FinalTySize < OrigTySize; 
  bool needsCast = false;

  if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Arg)) {
    switch (ICE->getCastKind()) {
    case CK_LValueToRValue:
    case CK_NoOp:
    case CK_UserDefinedConversion:
      break;

    case CK_IntegralCast: {
      if (MK == NSAPI::NSNumberWithBool && OrigTy->isBooleanType())
        break;
      // Be more liberal with Integer/UnsignedInteger which are very commonly
      // used.
      if ((MK == NSAPI::NSNumberWithInteger ||
           MK == NSAPI::NSNumberWithUnsignedInteger) &&
          !isTruncated) {
        if (OrigTy->getAs<EnumType>() || isEnumConstant(OrigArg))
          break;
        if ((MK==NSAPI::NSNumberWithInteger) == OrigTy->isSignedIntegerType() &&
            OrigTySize >= Ctx.getTypeSize(Ctx.IntTy))
          break;
      }

      needsCast = true;
      break;
    }

    case CK_PointerToBoolean:
    case CK_IntegralToBoolean:
    case CK_IntegralToFloating:
    case CK_FloatingToIntegral:
    case CK_FloatingToBoolean:
    case CK_FloatingCast:
    case CK_FloatingComplexToReal:
    case CK_FloatingComplexToBoolean:
    case CK_IntegralComplexToReal:
    case CK_IntegralComplexToBoolean:
    case CK_AtomicToNonAtomic:
    case CK_AddressSpaceConversion:
      needsCast = true;
      break;

    case CK_Dependent:
    case CK_BitCast:
    case CK_LValueBitCast:
    case CK_BaseToDerived:
    case CK_DerivedToBase:
    case CK_UncheckedDerivedToBase:
    case CK_Dynamic:
    case CK_ToUnion:
    case CK_ArrayToPointerDecay:
    case CK_FunctionToPointerDecay:
    case CK_NullToPointer:
    case CK_NullToMemberPointer:
    case CK_BaseToDerivedMemberPointer:
    case CK_DerivedToBaseMemberPointer:
    case CK_MemberPointerToBoolean:
    case CK_ReinterpretMemberPointer:
    case CK_ConstructorConversion:
    case CK_IntegralToPointer:
    case CK_PointerToIntegral:
    case CK_ToVoid:
    case CK_VectorSplat:
    case CK_CPointerToObjCPointerCast:
    case CK_BlockPointerToObjCPointerCast:
    case CK_AnyPointerToBlockPointerCast:
    case CK_ObjCObjectLValueCast:
    case CK_FloatingRealToComplex:
    case CK_FloatingComplexCast:
    case CK_FloatingComplexToIntegralComplex:
    case CK_IntegralRealToComplex:
    case CK_IntegralComplexCast:
    case CK_IntegralComplexToFloatingComplex:
    case CK_ARCProduceObject:
    case CK_ARCConsumeObject:
    case CK_ARCReclaimReturnedObject:
    case CK_ARCExtendBlockObject:
    case CK_NonAtomicToAtomic:
    case CK_CopyAndAutoreleaseBlockObject:
    case CK_BuiltinFnToFnPtr:
    case CK_ZeroToOCLEvent:
    case CK_ZeroToOCLQueue:
    case CK_IntToOCLSampler:
      return false;

    case CK_BooleanToSignedIntegral:
      llvm_unreachable("OpenCL-specific cast in Objective-C?");
    }
  }

  if (needsCast) {
    DiagnosticsEngine &Diags = Ctx.getDiagnostics(); 
    // FIXME: Use a custom category name to distinguish migration diagnostics.
    unsigned diagID = Diags.getCustomDiagID(DiagnosticsEngine::Warning,
                       "converting to boxing syntax requires casting %0 to %1");
    Diags.Report(Msg->getExprLoc(), diagID) << OrigTy << FinalTy
        << Msg->getSourceRange();
    return false;
  }

  SourceRange ArgRange = OrigArg->getSourceRange();
  commit.replaceWithInner(Msg->getSourceRange(), ArgRange);

  if (isa<ParenExpr>(OrigArg) || isa<IntegerLiteral>(OrigArg))
    commit.insertBefore(ArgRange.getBegin(), "@");
  else
    commit.insertWrap("@(", ArgRange, ")");

  return true;
}

//===----------------------------------------------------------------------===//
// rewriteToStringBoxedExpression.
//===----------------------------------------------------------------------===//

static bool doRewriteToUTF8StringBoxedExpressionHelper(
                                              const ObjCMessageExpr *Msg,
                                              const NSAPI &NS, Commit &commit) {
  const Expr *Arg = Msg->getArg(0);
  if (Arg->isTypeDependent())
    return false;

  ASTContext &Ctx = NS.getASTContext();

  const Expr *OrigArg = Arg->IgnoreImpCasts();
  QualType OrigTy = OrigArg->getType();
  if (OrigTy->isArrayType())
    OrigTy = Ctx.getArrayDecayedType(OrigTy);

  if (const StringLiteral *
        StrE = dyn_cast<StringLiteral>(OrigArg->IgnoreParens())) {
    commit.replaceWithInner(Msg->getSourceRange(), StrE->getSourceRange());
    commit.insert(StrE->getLocStart(), "@");
    return true;
  }

  if (const PointerType *PT = OrigTy->getAs<PointerType>()) {
    QualType PointeeType = PT->getPointeeType();
    if (Ctx.hasSameUnqualifiedType(PointeeType, Ctx.CharTy)) {
      SourceRange ArgRange = OrigArg->getSourceRange();
      commit.replaceWithInner(Msg->getSourceRange(), ArgRange);

      if (isa<ParenExpr>(OrigArg) || isa<IntegerLiteral>(OrigArg))
        commit.insertBefore(ArgRange.getBegin(), "@");
      else
        commit.insertWrap("@(", ArgRange, ")");
      
      return true;
    }
  }

  return false;
}

static bool rewriteToStringBoxedExpression(const ObjCMessageExpr *Msg,
                                           const NSAPI &NS, Commit &commit) {
  Selector Sel = Msg->getSelector();

  if (Sel == NS.getNSStringSelector(NSAPI::NSStr_stringWithUTF8String) ||
      Sel == NS.getNSStringSelector(NSAPI::NSStr_stringWithCString) ||
      Sel == NS.getNSStringSelector(NSAPI::NSStr_initWithUTF8String)) {
    if (Msg->getNumArgs() != 1)
      return false;
    return doRewriteToUTF8StringBoxedExpressionHelper(Msg, NS, commit);
  }

  if (Sel == NS.getNSStringSelector(NSAPI::NSStr_stringWithCStringEncoding)) {
    if (Msg->getNumArgs() != 2)
      return false;

    const Expr *encodingArg = Msg->getArg(1);
    if (NS.isNSUTF8StringEncodingConstant(encodingArg) ||
        NS.isNSASCIIStringEncodingConstant(encodingArg))
      return doRewriteToUTF8StringBoxedExpressionHelper(Msg, NS, commit);
  }

  return false;
}
