forked from OSchip/llvm-project
ObjectiveC migrator: Remove semicolon after the typedef
declaration when converting to NS_ENUM. This required some code refactoring. llvm-svn: 186619
This commit is contained in:
parent
4d56e9c1cb
commit
85e988bbea
|
@ -31,19 +31,8 @@ bool rewriteToObjCLiteralSyntax(const ObjCMessageExpr *Msg,
|
|||
const NSAPI &NS, Commit &commit,
|
||||
const ParentMap *PMap);
|
||||
|
||||
bool rewriteToObjCProperty(const ObjCMethodDecl *Getter,
|
||||
const ObjCMethodDecl *Setter,
|
||||
const NSAPI &NS, Commit &commit);
|
||||
bool rewriteToObjCInterfaceDecl(const ObjCInterfaceDecl *IDecl,
|
||||
llvm::SmallVectorImpl<ObjCProtocolDecl*> &Protocols,
|
||||
const NSAPI &NS, Commit &commit);
|
||||
|
||||
bool rewriteToObjCSubscriptSyntax(const ObjCMessageExpr *Msg,
|
||||
const NSAPI &NS, Commit &commit);
|
||||
|
||||
bool rewriteToNSEnumDecl(const EnumDecl *EnumDcl,
|
||||
const TypedefDecl *TypedefDcl,
|
||||
const NSAPI &NS, Commit &commit);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "Transforms.h"
|
||||
#include "clang/ARCMigrate/ARCMTActions.h"
|
||||
#include "clang/AST/ASTConsumer.h"
|
||||
#include "clang/AST/ASTContext.h"
|
||||
|
@ -199,6 +200,53 @@ void ObjCMigrateASTConsumer::migrateDecl(Decl *D) {
|
|||
BodyMigrator(*this).TraverseDecl(D);
|
||||
}
|
||||
|
||||
static bool rewriteToObjCProperty(const ObjCMethodDecl *Getter,
|
||||
const ObjCMethodDecl *Setter,
|
||||
const NSAPI &NS, edit::Commit &commit) {
|
||||
ASTContext &Context = NS.getASTContext();
|
||||
std::string PropertyString = "@property";
|
||||
const ParmVarDecl *argDecl = *Setter->param_begin();
|
||||
QualType ArgType = Context.getCanonicalType(argDecl->getType());
|
||||
Qualifiers::ObjCLifetime propertyLifetime = ArgType.getObjCLifetime();
|
||||
|
||||
if (ArgType->isObjCRetainableType() &&
|
||||
propertyLifetime == Qualifiers::OCL_Strong) {
|
||||
if (const ObjCObjectPointerType *ObjPtrTy =
|
||||
ArgType->getAs<ObjCObjectPointerType>()) {
|
||||
ObjCInterfaceDecl *IDecl = ObjPtrTy->getObjectType()->getInterface();
|
||||
if (IDecl &&
|
||||
IDecl->lookupNestedProtocol(&Context.Idents.get("NSCopying")))
|
||||
PropertyString += "(copy)";
|
||||
}
|
||||
}
|
||||
else if (propertyLifetime == Qualifiers::OCL_Weak)
|
||||
// TODO. More precise determination of 'weak' attribute requires
|
||||
// looking into setter's implementation for backing weak ivar.
|
||||
PropertyString += "(weak)";
|
||||
else
|
||||
PropertyString += "(unsafe_unretained)";
|
||||
|
||||
// strip off any ARC lifetime qualifier.
|
||||
QualType CanResultTy = Context.getCanonicalType(Getter->getResultType());
|
||||
if (CanResultTy.getQualifiers().hasObjCLifetime()) {
|
||||
Qualifiers Qs = CanResultTy.getQualifiers();
|
||||
Qs.removeObjCLifetime();
|
||||
CanResultTy = Context.getQualifiedType(CanResultTy.getUnqualifiedType(), Qs);
|
||||
}
|
||||
PropertyString += " ";
|
||||
PropertyString += CanResultTy.getAsString(Context.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;
|
||||
}
|
||||
|
||||
void ObjCMigrateASTConsumer::migrateObjCInterfaceDecl(ASTContext &Ctx,
|
||||
ObjCInterfaceDecl *D) {
|
||||
for (ObjCContainerDecl::method_iterator M = D->meth_begin(), MEnd = D->meth_end();
|
||||
|
@ -231,7 +279,7 @@ void ObjCMigrateASTConsumer::migrateObjCInterfaceDecl(ASTContext &Ctx,
|
|||
SetterMethod->hasAttrs())
|
||||
continue;
|
||||
edit::Commit commit(*Editor);
|
||||
edit::rewriteToObjCProperty(Method, SetterMethod, *NSAPIObj, commit);
|
||||
rewriteToObjCProperty(Method, SetterMethod, *NSAPIObj, commit);
|
||||
Editor->commit(commit);
|
||||
}
|
||||
}
|
||||
|
@ -300,6 +348,55 @@ ClassImplementsAllMethodsAndProperties(ASTContext &Ctx,
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool rewriteToObjCInterfaceDecl(const ObjCInterfaceDecl *IDecl,
|
||||
llvm::SmallVectorImpl<ObjCProtocolDecl*> &ConformingProtocols,
|
||||
const NSAPI &NS, edit::Commit &commit) {
|
||||
const ObjCList<ObjCProtocolDecl> &Protocols = IDecl->getReferencedProtocols();
|
||||
std::string ClassString;
|
||||
SourceLocation EndLoc =
|
||||
IDecl->getSuperClass() ? IDecl->getSuperClassLoc() : IDecl->getLocation();
|
||||
|
||||
if (Protocols.empty()) {
|
||||
ClassString = '<';
|
||||
for (unsigned i = 0, e = ConformingProtocols.size(); i != e; i++) {
|
||||
ClassString += ConformingProtocols[i]->getNameAsString();
|
||||
if (i != (e-1))
|
||||
ClassString += ", ";
|
||||
}
|
||||
ClassString += "> ";
|
||||
}
|
||||
else {
|
||||
ClassString = ", ";
|
||||
for (unsigned i = 0, e = ConformingProtocols.size(); i != e; i++) {
|
||||
ClassString += ConformingProtocols[i]->getNameAsString();
|
||||
if (i != (e-1))
|
||||
ClassString += ", ";
|
||||
}
|
||||
ObjCInterfaceDecl::protocol_loc_iterator PL = IDecl->protocol_loc_end() - 1;
|
||||
EndLoc = *PL;
|
||||
}
|
||||
|
||||
commit.insertAfterToken(EndLoc, ClassString);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool rewriteToNSEnumDecl(const EnumDecl *EnumDcl,
|
||||
const TypedefDecl *TypedefDcl,
|
||||
const NSAPI &NS, edit::Commit &commit) {
|
||||
std::string ClassString = "typedef NS_ENUM(NSInteger, ";
|
||||
ClassString += TypedefDcl->getIdentifier()->getName();
|
||||
ClassString += ')';
|
||||
SourceRange R(EnumDcl->getLocStart(), EnumDcl->getLocStart());
|
||||
commit.replace(R, ClassString);
|
||||
SourceLocation EndOfTypedefLoc = TypedefDcl->getLocEnd();
|
||||
EndOfTypedefLoc = trans::findLocationAfterSemi(EndOfTypedefLoc, NS.getASTContext());
|
||||
if (!EndOfTypedefLoc.isInvalid()) {
|
||||
commit.remove(SourceRange(TypedefDcl->getLocStart(), EndOfTypedefLoc));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void ObjCMigrateASTConsumer::migrateProtocolConformance(ASTContext &Ctx,
|
||||
const ObjCImplementationDecl *ImpDecl) {
|
||||
const ObjCInterfaceDecl *IDecl = ImpDecl->getClassInterface();
|
||||
|
@ -352,8 +449,8 @@ void ObjCMigrateASTConsumer::migrateProtocolConformance(ASTContext &Ctx,
|
|||
MinimalConformingProtocols.push_back(TargetPDecl);
|
||||
}
|
||||
edit::Commit commit(*Editor);
|
||||
edit::rewriteToObjCInterfaceDecl(IDecl, MinimalConformingProtocols,
|
||||
*NSAPIObj, commit);
|
||||
rewriteToObjCInterfaceDecl(IDecl, MinimalConformingProtocols,
|
||||
*NSAPIObj, commit);
|
||||
Editor->commit(commit);
|
||||
}
|
||||
|
||||
|
@ -372,7 +469,7 @@ void ObjCMigrateASTConsumer::migrateNSEnumDecl(ASTContext &Ctx,
|
|||
if (!Ctx.Idents.get("NS_ENUM").hasMacroDefinition())
|
||||
return;
|
||||
edit::Commit commit(*Editor);
|
||||
edit::rewriteToNSEnumDecl(EnumDcl, TypedefDcl, *NSAPIObj, commit);
|
||||
rewriteToNSEnumDecl(EnumDcl, TypedefDcl, *NSAPIObj, commit);
|
||||
Editor->commit(commit);
|
||||
}
|
||||
|
||||
|
|
|
@ -355,98 +355,6 @@ bool edit::rewriteToObjCLiteralSyntax(const ObjCMessageExpr *Msg,
|
|||
return false;
|
||||
}
|
||||
|
||||
bool edit::rewriteToObjCProperty(const ObjCMethodDecl *Getter,
|
||||
const ObjCMethodDecl *Setter,
|
||||
const NSAPI &NS, Commit &commit) {
|
||||
ASTContext &Context = NS.getASTContext();
|
||||
std::string PropertyString = "@property";
|
||||
const ParmVarDecl *argDecl = *Setter->param_begin();
|
||||
QualType ArgType = Context.getCanonicalType(argDecl->getType());
|
||||
Qualifiers::ObjCLifetime propertyLifetime = ArgType.getObjCLifetime();
|
||||
|
||||
if (ArgType->isObjCRetainableType() &&
|
||||
propertyLifetime == Qualifiers::OCL_Strong) {
|
||||
if (const ObjCObjectPointerType *ObjPtrTy =
|
||||
ArgType->getAs<ObjCObjectPointerType>()) {
|
||||
ObjCInterfaceDecl *IDecl = ObjPtrTy->getObjectType()->getInterface();
|
||||
if (IDecl &&
|
||||
IDecl->lookupNestedProtocol(&Context.Idents.get("NSCopying")))
|
||||
PropertyString += "(copy)";
|
||||
}
|
||||
}
|
||||
else if (propertyLifetime == Qualifiers::OCL_Weak)
|
||||
// TODO. More precise determination of 'weak' attribute requires
|
||||
// looking into setter's implementation for backing weak ivar.
|
||||
PropertyString += "(weak)";
|
||||
else
|
||||
PropertyString += "(unsafe_unretained)";
|
||||
|
||||
// strip off any ARC lifetime qualifier.
|
||||
QualType CanResultTy = Context.getCanonicalType(Getter->getResultType());
|
||||
if (CanResultTy.getQualifiers().hasObjCLifetime()) {
|
||||
Qualifiers Qs = CanResultTy.getQualifiers();
|
||||
Qs.removeObjCLifetime();
|
||||
CanResultTy = Context.getQualifiedType(CanResultTy.getUnqualifiedType(), Qs);
|
||||
}
|
||||
PropertyString += " ";
|
||||
PropertyString += CanResultTy.getAsString(Context.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;
|
||||
}
|
||||
|
||||
bool edit::rewriteToObjCInterfaceDecl(const ObjCInterfaceDecl *IDecl,
|
||||
llvm::SmallVectorImpl<ObjCProtocolDecl*> &ConformingProtocols,
|
||||
const NSAPI &NS, Commit &commit) {
|
||||
const ObjCList<ObjCProtocolDecl> &Protocols = IDecl->getReferencedProtocols();
|
||||
std::string ClassString;
|
||||
SourceLocation EndLoc =
|
||||
IDecl->getSuperClass() ? IDecl->getSuperClassLoc() : IDecl->getLocation();
|
||||
|
||||
if (Protocols.empty()) {
|
||||
ClassString = '<';
|
||||
for (unsigned i = 0, e = ConformingProtocols.size(); i != e; i++) {
|
||||
ClassString += ConformingProtocols[i]->getNameAsString();
|
||||
if (i != (e-1))
|
||||
ClassString += ", ";
|
||||
}
|
||||
ClassString += "> ";
|
||||
}
|
||||
else {
|
||||
ClassString = ", ";
|
||||
for (unsigned i = 0, e = ConformingProtocols.size(); i != e; i++) {
|
||||
ClassString += ConformingProtocols[i]->getNameAsString();
|
||||
if (i != (e-1))
|
||||
ClassString += ", ";
|
||||
}
|
||||
ObjCInterfaceDecl::protocol_loc_iterator PL = IDecl->protocol_loc_end() - 1;
|
||||
EndLoc = *PL;
|
||||
}
|
||||
|
||||
commit.insertAfterToken(EndLoc, ClassString);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool edit::rewriteToNSEnumDecl(const EnumDecl *EnumDcl,
|
||||
const TypedefDecl *TypedefDcl,
|
||||
const NSAPI &NS, Commit &commit) {
|
||||
std::string ClassString = "typedef NS_ENUM(NSInteger, ";
|
||||
ClassString += TypedefDcl->getIdentifier()->getName();
|
||||
ClassString += ')';
|
||||
SourceRange R(EnumDcl->getLocStart(), EnumDcl->getLocStart());
|
||||
commit.replace(R, ClassString);
|
||||
commit.remove(SourceRange(TypedefDcl->getLocStart(), TypedefDcl->getLocEnd()));
|
||||
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.
|
||||
|
|
|
@ -10,4 +10,4 @@ typedef NS_ENUM(NSInteger, wibble) {
|
|||
blah,
|
||||
blarg
|
||||
};
|
||||
;
|
||||
|
||||
|
|
Loading…
Reference in New Issue