Kaydet (Commit) 395d6a96 authored tarafından Bjoern Michaelsen's avatar Bjoern Michaelsen Kaydeden (comit) Björn Michaelsen

cascading conditional operators, give a hint on complexity

Change-Id: Ie9d0b07a32cc17705db735ea18f70f28d57badd4
Reviewed-on: https://gerrit.libreoffice.org/12990Reviewed-by: 's avatarBjörn Michaelsen <bjoern.michaelsen@canonical.com>
Tested-by: 's avatarBjörn Michaelsen <bjoern.michaelsen@canonical.com>
üst 2851ce5a
......@@ -14,8 +14,8 @@
/*
This is a compile check.
It checks for conditional operators in conditional operators, which are
errorprone, e.g.
It checks for complex statements with conditional operators in conditional
operators, which are errorprone, e.g.
Thing foo = IsBar() ? ( IsBaz() ? b1 : b2 ) : b3;
However, it finds 556 cases in sw/source alone, thus likely needs some more
......@@ -24,9 +24,19 @@ a certain length in characters (but that needs the Context/SourceManager, which
I havent played with yet).
*/
// the value is rather arbitrary, but code above this number of stmts begins to
// be smelly
static const int stmtlimit = 50;
namespace loplugin
{
struct WalkCounter
{
int stmtcount;
bool cascading;
};
// Ctor, nothing special, pass the argument(s).
CascadingCondOp::CascadingCondOp( const InstantiationData& data )
: Plugin( data )
......@@ -41,20 +51,30 @@ void CascadingCondOp::run()
TraverseDecl( compiler.getASTContext().getTranslationUnitDecl());
}
void CascadingCondOp::Walk( const Stmt* stmt )
void CascadingCondOp::Walk( const Stmt* stmt, WalkCounter& c )
{
for(Stmt::const_child_iterator it = stmt->child_begin(); it != stmt->child_end(); ++it)
{
if ( const ConditionalOperator* condop = dyn_cast< ConditionalOperator >( *it ))
report( DiagnosticsEngine::Warning, "cascading conditional operator", condop->getLocStart());
Walk(*it);
++c.stmtcount;
if ( dyn_cast< ConditionalOperator >( *it ))
c.cascading = true;
Walk(*it, c);
}
}
bool CascadingCondOp::VisitStmt( const Stmt* stmt )
{
if ( const ConditionalOperator* condop = dyn_cast< ConditionalOperator >( stmt ))
Walk(condop);
{
WalkCounter c = { 0, false };
Walk(condop, c);
if(c.cascading && c.stmtcount >= stmtlimit)
{
std::string msg("cascading conditional operator, complexity: ");
msg.append(std::to_string(c.stmtcount));
report( DiagnosticsEngine::Warning, msg, condop->getLocStart());
}
}
return true;
}
......
......@@ -17,6 +17,8 @@
namespace loplugin
{
struct WalkCounter;
// The class implementing the plugin action.
class CascadingCondOp
// Inherits from the Clang class that will allow examing the Clang AST tree (i.e. syntax tree).
......@@ -27,7 +29,7 @@ class CascadingCondOp
public:
CascadingCondOp( const InstantiationData& data );
virtual void run() override;
void Walk( const Stmt* stmt );
void Walk( const Stmt* stmt, WalkCounter& c );
bool VisitStmt( const Stmt* stmt );
};
......
......@@ -358,4 +358,13 @@ SwEditShell* SwDoc::GetEditShell()
return GetEditShell();
}
//bool foo()
//{
// bool b1 = true ? true : false;
// bool b2 = (true ? true : false) ? true : false;
// bool b3 = true ? (true ? true : false) : false;
// bool b4 = true ? true : (true ? true : false);
// return false;
//}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment