Refactor the same expression check

Work out if a function is inconclusive when creating the entry in the
Expressions class instead of when checking the counts at the end. Store
the result in a new bool flag in the ExpressionTokens helper struct.

The pointer to symbol database and ref to list of const functions are
temporarily stored in  the Expressions helper class to avoid passing
them in too on every endExpr(tok) call.

Use a const reference to ExpressionTokens in the check loop to avoid
repeating the it->second several times, which clarifies what that code
does.
This commit is contained in:
Richard Quirk 2011-12-01 19:46:57 +01:00
parent 5017646488
commit a880469c5a
1 changed files with 49 additions and 42 deletions

View File

@ -2386,47 +2386,14 @@ namespace {
const Token *start;
const Token *end;
int count;
ExpressionTokens(const Token *s, const Token *e): start(s), end(e), count(1) {}
};
class Expressions {
public:
Expressions(): _start(0) {}
void endExpr(const Token *end) {
const std::string &e = _expression.str();
if (!e.empty()) {
std::map<std::string, ExpressionTokens>::iterator it = _expressions.find(e);
if (it == _expressions.end())
_expressions.insert(std::make_pair(e, ExpressionTokens(_start, end)));
else
it->second.count += 1;
}
_expression.str("");
_start = 0;
}
void append(const Token *tok) {
if (!_start)
_start = tok;
_expression << tok->str();
}
std::map<std::string,ExpressionTokens> &getMap() {
return _expressions;
}
private:
std::map<std::string, ExpressionTokens> _expressions;
std::ostringstream _expression;
const Token *_start;
bool inconclusiveFunction;
ExpressionTokens(const Token *s, const Token *e): start(s), end(e), count(1), inconclusiveFunction(false) {}
};
struct FuncFilter {
FuncFilter(const Scope *scope, const Token *tok): _scope(scope), _tok(tok) {}
bool operator()(const Function &func) {
// todo: function args, etc??
bool matchingFunc = func.type == Function::eFunction &&
_tok->str() == func.token->str();
// either a class function, or a global function with the same name
@ -2437,7 +2404,6 @@ namespace {
const Token *_tok;
};
bool inconclusiveFunctionCall(const SymbolDatabase *symbolDatabase,
const std::list<Function> &constFunctions,
const ExpressionTokens &tokens)
@ -2473,6 +2439,49 @@ namespace {
return false;
}
class Expressions {
public:
Expressions(const SymbolDatabase *symbolDatabase, const
std::list<Function> &constFunctions)
: _start(0),
_symbolDatabase(symbolDatabase),
_constFunctions(constFunctions) { }
void endExpr(const Token *end) {
const std::string &e = _expression.str();
if (!e.empty()) {
std::map<std::string, ExpressionTokens>::iterator it = _expressions.find(e);
if (it == _expressions.end()) {
ExpressionTokens exprTokens(_start, end);
exprTokens.inconclusiveFunction = inconclusiveFunctionCall(
_symbolDatabase, _constFunctions, exprTokens);
_expressions.insert(std::make_pair(e, exprTokens));
} else {
it->second.count += 1;
}
}
_expression.str("");
_start = 0;
}
void append(const Token *tok) {
if (!_start)
_start = tok;
_expression << tok->str();
}
std::map<std::string,ExpressionTokens> &getMap() {
return _expressions;
}
private:
std::map<std::string, ExpressionTokens> _expressions;
std::ostringstream _expression;
const Token *_start;
const SymbolDatabase *_symbolDatabase;
const std::list<Function> &_constFunctions;
};
bool notconst(const Function &func)
{
return !func.isConst;
@ -2520,7 +2529,7 @@ void CheckOther::checkExpressionRange(const std::list<Function> &constFunctions,
{
if (!start || !end)
return;
Expressions expressions;
Expressions expressions(_tokenizer->getSymbolDatabase(), constFunctions);
std::string opName;
int level = 0;
for (const Token *tok = start->next(); tok && tok != end; tok = tok->next()) {
@ -2538,7 +2547,6 @@ void CheckOther::checkExpressionRange(const std::list<Function> &constFunctions,
}
expressions.endExpr(end);
std::map<std::string,ExpressionTokens>::const_iterator it = expressions.getMap().begin();
const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase();
for (; it != expressions.getMap().end(); ++it) {
// check expression..
bool valid = true;
@ -2571,10 +2579,9 @@ void CheckOther::checkExpressionRange(const std::list<Function> &constFunctions,
if (!valid || parantheses!=0 || brackets!=0)
continue;
if (it->second.count > 1 &&
(it->first.find("(") == std::string::npos ||
!inconclusiveFunctionCall(symbolDatabase, constFunctions, it->second))) {
duplicateExpressionError(it->second.start, it->second.start, opName);
const ExpressionTokens &expr = it->second;
if (expr.count > 1 && !expr.inconclusiveFunction) {
duplicateExpressionError(expr.start, expr.start, opName);
}
}
}