forked from OSchip/llvm-project
[ASTMatchers] Introduce Objective-C matchers `hasReceiver` and `isInstanceMessage` for ObjCMessageExpr
Differential Revision: https://reviews.llvm.org/D49333 llvm-svn: 337209
This commit is contained in:
parent
5da636fb90
commit
b5ea4df0eb
|
@ -3268,6 +3268,19 @@ represent an error condition in the tree!
|
|||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1ObjCMessageExpr.html">ObjCMessageExpr</a>></td><td class="name" onclick="toggle('isInstanceMessage0')"><a name="isInstanceMessage0Anchor">isInstanceMessage</a></td><td></td></tr>
|
||||
<tr><td colspan="4" class="doc" id="isInstanceMessage0"><pre>Returns true when the Objective-C message is sent to an instance.
|
||||
|
||||
Example
|
||||
matcher = objcMessagaeExpr(isInstanceMessage())
|
||||
matches
|
||||
NSString *x = @"hello";
|
||||
[x containsString:@"h"]
|
||||
but not
|
||||
[NSString stringWithFormat:@"format"]
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1ObjCMessageExpr.html">ObjCMessageExpr</a>></td><td class="name" onclick="toggle('matchesSelector0')"><a name="matchesSelector0Anchor">matchesSelector</a></td><td>std::string RegExp</td></tr>
|
||||
<tr><td colspan="4" class="doc" id="matchesSelector0"><pre>Matches ObjC selectors whose name contains
|
||||
a substring matched by the given RegExp.
|
||||
|
@ -5875,6 +5888,18 @@ Example matches y in x(y)
|
|||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1ObjCMessageExpr.html">ObjCMessageExpr</a>></td><td class="name" onclick="toggle('hasReceiver0')"><a name="hasReceiver0Anchor">hasReceiver</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>> InnerMatcher</td></tr>
|
||||
<tr><td colspan="4" class="doc" id="hasReceiver0"><pre>Matches if the Objective-C message is sent to an instance,
|
||||
and the inner matcher matches on that instance.
|
||||
|
||||
For example the method call in
|
||||
NSString *x = @"hello";
|
||||
[x containsString:@"h"]
|
||||
is matched by
|
||||
objcMessageExpr(hasReceiver(declRefExpr(to(varDecl(hasName("x"))))))
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1ObjCMessageExpr.html">ObjCMessageExpr</a>></td><td class="name" onclick="toggle('hasReceiverType0')"><a name="hasReceiverType0Anchor">hasReceiverType</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>> InnerMatcher</td></tr>
|
||||
<tr><td colspan="4" class="doc" id="hasReceiverType0"><pre>Matches on the receiver of an ObjectiveC Message expression.
|
||||
|
||||
|
|
|
@ -2736,6 +2736,41 @@ AST_MATCHER_P(ObjCMessageExpr, hasReceiverType, internal::Matcher<QualType>,
|
|||
return InnerMatcher.matches(TypeDecl, Finder, Builder);
|
||||
}
|
||||
|
||||
/// Returns true when the Objective-C message is sent to an instance.
|
||||
///
|
||||
/// Example
|
||||
/// matcher = objcMessagaeExpr(isInstanceMessage())
|
||||
/// matches
|
||||
/// \code
|
||||
/// NSString *x = @"hello";
|
||||
/// [x containsString:@"h"];
|
||||
/// \endcode
|
||||
/// but not
|
||||
/// \code
|
||||
/// [NSString stringWithFormat:@"format"];
|
||||
/// \endcode
|
||||
AST_MATCHER(ObjCMessageExpr, isInstanceMessage) {
|
||||
return Node.isInstanceMessage();
|
||||
}
|
||||
|
||||
/// Matches if the Objective-C message is sent to an instance,
|
||||
/// and the inner matcher matches on that instance.
|
||||
///
|
||||
/// For example the method call in
|
||||
/// \code
|
||||
/// NSString *x = @"hello";
|
||||
/// [x containsString:@"h"];
|
||||
/// \endcode
|
||||
/// is matched by
|
||||
/// objcMessageExpr(hasReceiver(declRefExpr(to(varDecl(hasName("x"))))))
|
||||
AST_MATCHER_P(ObjCMessageExpr, hasReceiver, internal::Matcher<Expr>,
|
||||
InnerMatcher) {
|
||||
const Expr *ReceiverNode = Node.getInstanceReceiver();
|
||||
return (ReceiverNode != nullptr &&
|
||||
InnerMatcher.matches(*ReceiverNode->IgnoreParenImpCasts(), Finder,
|
||||
Builder));
|
||||
}
|
||||
|
||||
/// Matches when BaseName == Selector.getAsString()
|
||||
///
|
||||
/// matcher = objCMessageExpr(hasSelector("loadHTMLString:baseURL:"));
|
||||
|
|
|
@ -283,6 +283,7 @@ RegistryMaps::RegistryMaps() {
|
|||
REGISTER_MATCHER(hasParent);
|
||||
REGISTER_MATCHER(hasQualifier);
|
||||
REGISTER_MATCHER(hasRangeInit);
|
||||
REGISTER_MATCHER(hasReceiver);
|
||||
REGISTER_MATCHER(hasReceiverType);
|
||||
REGISTER_MATCHER(hasReplacementType);
|
||||
REGISTER_MATCHER(hasReturnValue);
|
||||
|
@ -349,6 +350,7 @@ RegistryMaps::RegistryMaps() {
|
|||
REGISTER_MATCHER(isImplicit);
|
||||
REGISTER_MATCHER(isExpansionInFileMatching);
|
||||
REGISTER_MATCHER(isExpansionInMainFile);
|
||||
REGISTER_MATCHER(isInstanceMessage);
|
||||
REGISTER_MATCHER(isInstantiated);
|
||||
REGISTER_MATCHER(isExpansionInSystemHeader);
|
||||
REGISTER_MATCHER(isInteger);
|
||||
|
|
|
@ -422,6 +422,35 @@ TEST(Matcher, AnyArgument) {
|
|||
EXPECT_TRUE(matches("void x(long) { int y; x(y); }", ImplicitCastedArgument));
|
||||
}
|
||||
|
||||
TEST(Matcher, HasReceiver) {
|
||||
EXPECT_TRUE(matchesObjC(
|
||||
"@interface NSString @end"
|
||||
"void f(NSString *x) {"
|
||||
"[x containsString]"
|
||||
"}",
|
||||
objcMessageExpr(hasReceiver(declRefExpr(to(varDecl(hasName("x"))))))));
|
||||
|
||||
EXPECT_FALSE(matchesObjC(
|
||||
"@interface NSString +(NSString *) stringWithFormat; @end"
|
||||
"void f() { [NSString stringWithFormat]; }",
|
||||
objcMessageExpr(hasReceiver(declRefExpr(to(varDecl(hasName("x"))))))));
|
||||
}
|
||||
|
||||
TEST(Matcher, isInstanceMessage) {
|
||||
EXPECT_TRUE(matchesObjC(
|
||||
"@interface NSString @end"
|
||||
"void f(NSString *x) {"
|
||||
"[x containsString]"
|
||||
"}",
|
||||
objcMessageExpr(isInstanceMessage())));
|
||||
|
||||
EXPECT_FALSE(matchesObjC(
|
||||
"@interface NSString +(NSString *) stringWithFormat; @end"
|
||||
"void f() { [NSString stringWithFormat]; }",
|
||||
objcMessageExpr(isInstanceMessage())));
|
||||
|
||||
}
|
||||
|
||||
TEST(ForEachArgumentWithParam, ReportsNoFalsePositives) {
|
||||
StatementMatcher ArgumentY =
|
||||
declRefExpr(to(varDecl(hasName("y")))).bind("arg");
|
||||
|
|
Loading…
Reference in New Issue