diff options
author | Sergio Martins <iamsergio@gmail.com> | 2017-12-01 14:10:49 +0000 |
---|---|---|
committer | Sergio Martins <iamsergio@gmail.com> | 2017-12-01 14:10:49 +0000 |
commit | 41e79d655cd7133459706e17ab8cf794ce4e5251 (patch) | |
tree | 9dbc86fca6a4ad2f821c3b8dde2fae38176442b5 /src | |
parent | 21b73fbb4f49f6ef3f4dbc9d15165e67e70dfd8b (diff) |
connect-3arg-lambda: refactor this check
No longer advises to pass 'this' as 3rd argument, because it might
make sense to pass another object there, should be the user to decide.
Diffstat (limited to 'src')
-rw-r--r-- | src/checks/level1/connect-3arg-lambda.cpp | 39 |
1 files changed, 22 insertions, 17 deletions
diff --git a/src/checks/level1/connect-3arg-lambda.cpp b/src/checks/level1/connect-3arg-lambda.cpp index e036f6f8..12148907 100644 --- a/src/checks/level1/connect-3arg-lambda.cpp +++ b/src/checks/level1/connect-3arg-lambda.cpp @@ -52,31 +52,30 @@ void Connect3argLambda::VisitStmt(clang::Stmt *stmt) if (!lambda) return; - // The sender can be: this - auto senderThis = HierarchyUtils::unpeal<CXXThisExpr>(callExpr->getArg(0), HierarchyUtils::IgnoreImplicitCasts); + DeclRefExpr *senderDeclRef = nullptr; + MemberExpr *senderMemberExpr = nullptr; - // Or it can be: a declref (variable) - DeclRefExpr *senderDeclRef = senderThis ? nullptr : HierarchyUtils::getFirstChildOfType2<DeclRefExpr>(callExpr->getArg(0)); + Stmt *s = callExpr->getArg(0); + while (s) { + if ((senderDeclRef = dyn_cast<DeclRefExpr>(s))) + break; + if ((senderMemberExpr = dyn_cast<MemberExpr>(s))) + break; - // If this is referenced inside the lambda body, for example, by calling a member function - auto thisExprs = HierarchyUtils::getStatements<CXXThisExpr>(lambda->getBody()); - const bool lambdaHasThis = !thisExprs.empty(); + s = HierarchyUtils::getFirstChild(s); + } - // The variables used inside the lambda - auto declrefs = HierarchyUtils::getStatements<DeclRefExpr>(lambda->getBody()); - // If lambda doesn't do anything interesting, don't warn - if (declrefs.empty() && !lambdaHasThis) - return; + // The sender can be: this + CXXThisExpr* senderThis = HierarchyUtils::unpeal<CXXThisExpr>(callExpr->getArg(0), HierarchyUtils::IgnoreImplicitCasts); - if (lambdaHasThis && !senderThis && QtUtils::isQObject(thisExprs[0]->getType())) { - emitWarning(stmt->getLocStart(), "Pass 'this' as the 3rd connect parameter"); - return; - } + // The variables used inside the lambda + auto declrefs = HierarchyUtils::getStatements<DeclRefExpr>(lambda->getBody()); ValueDecl *senderDecl = senderDeclRef ? senderDeclRef->getDecl() : nullptr; - // We'll only warn if the lambda is dereferencing another QObject (besides the sender). + + // We'll only warn if the lambda is dereferencing another QObject (besides the sender) bool found = false; for (auto declref : declrefs) { ValueDecl *decl = declref->getDecl(); @@ -89,6 +88,12 @@ void Connect3argLambda::VisitStmt(clang::Stmt *stmt) } } + if (!found) { + auto thisexprs = HierarchyUtils::getStatements<CXXThisExpr>(lambda->getBody()); + if (!thisexprs.empty() && !senderThis) + found = true; + } + if (found) emitWarning(stmt->getLocStart(), "Pass a context object as 3rd connect parameter"); } |