//===--- 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 = 0;
  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 = 0;
  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;
}

bool edit::rewriteToObjCProperty(const ObjCMethodDecl *Getter,
                                 const ObjCMethodDecl *Setter,
                                 const NSAPI &NS, Commit &commit) {
  std::string PropertyString = "@property";
  const ParmVarDecl *argDecl = *Setter->param_begin();
  QualType ArgType = argDecl->getType();
  Qualifiers::ObjCLifetime propertyLifetime = ArgType.getObjCLifetime();
  if (propertyLifetime != Qualifiers::OCL_None) {
    PropertyString += "(";
    if (propertyLifetime == Qualifiers::OCL_Strong)
      PropertyString += "strong";
    else if (propertyLifetime == Qualifiers::OCL_Weak)
      PropertyString += "weak";
    else
      PropertyString += "unsafe_unretained";
    PropertyString += ")";
  }
  QualType PropQT = Getter->getResultType();
  PropertyString += " ";
  PropertyString += PropQT.getAsString(NS.getASTContext().getPrintingPolicy());
  PropertyString += " ";
  PropertyString += Getter->getNameAsString();
  commit.replace(CharSourceRange::getCharRange(Getter->getLocStart(),
                                               Getter->getDeclaratorEndLoc()),
                 PropertyString);
  SourceLocation EndLoc = Setter->getDeclaratorEndLoc();
  // Get location past ';'
  EndLoc = EndLoc.getLocWithOffset(1);
  commit.remove(CharSourceRange::getCharRange(Setter->getLocStart(), EndLoc));
  return true;
}

/// \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 = 0;
    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 = 0;
  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:
      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:
      return false;
    }
  }

  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)) {
    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;
}
