10 #include "clang/AST/ASTContext.h" 11 #include "clang/ASTMatchers/ASTMatchFinder.h" 12 #include "clang/Basic/LangOptions.h" 13 #include "clang/Basic/SourceLocation.h" 14 #include "clang/Basic/SourceManager.h" 15 #include "llvm/Support/FormatVariadic.h" 27 SourceLocation ReceiverLocation = Expr->getReceiverRange().getBegin();
28 if (ReceiverLocation.isMacroID())
31 SourceLocation SelectorLocation = Expr->getSelectorStartLoc();
32 if (SelectorLocation.isMacroID())
41 while (ClassDecl !=
nullptr) {
42 for (
const auto *MethodDecl : ClassDecl->instance_methods()) {
43 if (MethodDecl->getSelector().getAsString() ==
"init")
44 return !MethodDecl->isUnavailable();
46 ClassDecl = ClassDecl->getSuperClass();
61 const SourceManager &SM,
62 const LangOptions &LangOpts) {
63 CharSourceRange CharRange = Lexer::makeFileCharRange(
65 return Lexer::getSourceText(CharRange, SM, LangOpts);
69 const SourceManager &SM,
70 const LangOptions &LangOpts) {
76 std::map<StringRef, StringRef> ClassToFactoryMethodMap = {{
"NSDate",
"date"},
78 auto FoundClassFactory = ClassToFactoryMethodMap.find(Receiver);
79 if (FoundClassFactory != ClassToFactoryMethodMap.end()) {
80 StringRef ClassName = FoundClassFactory->first;
81 StringRef FactorySelector = FoundClassFactory->second;
83 llvm::formatv(
"[{0} {1}]", ClassName, FactorySelector);
84 return FixItHint::CreateReplacement(Expr->getSourceRange(), NewCall);
88 std::string NewCall = llvm::formatv(
"[[{0} alloc] init]", Receiver);
89 return FixItHint::CreateReplacement(Expr->getSourceRange(), NewCall);
95 void AvoidNSObjectNewCheck::registerMatchers(MatchFinder *Finder) {
96 if (!getLangOpts().ObjC)
101 objcMessageExpr(isClassMessage(), hasSelector(
"new")).bind(
"new_call"),
104 objcMethodDecl(isClassMethod(), isDefinition(), hasName(
"new"))
105 .bind(
"new_override"),
109 void AvoidNSObjectNewCheck::check(
const MatchFinder::MatchResult &
Result) {
110 if (
const auto *CallExpr =
111 Result.Nodes.getNodeAs<ObjCMessageExpr>(
"new_call")) {
116 diag(CallExpr->getExprLoc(),
"do not create objects with +new")
118 Result.Context->getLangOpts());
121 if (
const auto *DeclExpr =
122 Result.Nodes.getNodeAs<ObjCMethodDecl>(
"new_override")) {
123 diag(DeclExpr->getBeginLoc(),
"classes should not override +new");
static bool isMessageExpressionInsideMacro(const ObjCMessageExpr *Expr)
static StringRef getReceiverString(SourceRange ReceiverRange, const SourceManager &SM, const LangOptions &LangOpts)
llvm::Optional< Range > getTokenRange(const SourceManager &SM, const LangOptions &LangOpts, SourceLocation TokLoc)
Returns the taken range at TokLoc.
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
llvm::Optional< llvm::Expected< tooling::AtomicChanges > > Result
static FixItHint getCallFixItHint(const ObjCMessageExpr *Expr, const SourceManager &SM, const LangOptions &LangOpts)
static bool isInitMethodAvailable(const ObjCInterfaceDecl *ClassDecl)