Refactorizations in SymbolDatabase:
- Moved complete evaluation of variables type into one function executed when the variable is constructed - Moved SymbolDatabase::ArrayDimensions to Variable::ArrayDimensions
This commit is contained in:
parent
11a296cb02
commit
0452b03f53
|
@ -121,25 +121,14 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti
|
|||
Scope *new_scope = &scopeList.back();
|
||||
access[new_scope] = Public;
|
||||
|
||||
std::vector<Dimension> dimensions;
|
||||
|
||||
bool isPointer = false;
|
||||
bool isReference = false;
|
||||
bool isArray = false;
|
||||
|
||||
const Token* varNameTok = tok->next()->link()->next();
|
||||
if (varNameTok->str() == "*") {
|
||||
isPointer = true;
|
||||
varNameTok = varNameTok->next();
|
||||
} else if (varNameTok->str() == "&") {
|
||||
isReference = true;
|
||||
varNameTok = varNameTok->next();
|
||||
}
|
||||
|
||||
if (varNameTok->next()->str() == "[")
|
||||
isArray = arrayDimensions(dimensions, varNameTok->next());
|
||||
|
||||
scope->addVariable(varNameTok, tok, tok, access[scope], false, false, false, true, new_scope, scope, isArray, isPointer, isReference, dimensions);
|
||||
scope->addVariable(varNameTok, tok, tok, access[scope], new_scope, scope);
|
||||
|
||||
const Token *tok2 = tok->next();
|
||||
|
||||
|
@ -817,6 +806,39 @@ bool SymbolDatabase::isFunction(const Token *tok, const Scope* outerScope, const
|
|||
return false;
|
||||
}
|
||||
|
||||
void Variable::evaluate()
|
||||
{
|
||||
const Token* tok = _start;
|
||||
if (tok && tok->previous() && tok->previous()->isName())
|
||||
tok = tok->previous();
|
||||
for (; tok != _name; tok = tok->next()) {
|
||||
if (tok->str() == "<")
|
||||
tok->findClosingBracket(tok);
|
||||
if (tok->str() == "static")
|
||||
setFlag(fIsStatic, true);
|
||||
else if (tok->str() == "mutable")
|
||||
setFlag(fIsMutable, true);
|
||||
else if (tok->str() == "const")
|
||||
setFlag(fIsConst, true);
|
||||
else if (tok->str() == "*") {
|
||||
setFlag(fIsPointer, true);
|
||||
setFlag(fIsConst, false); // Points to const, isn't necessarily const itself
|
||||
} else if (tok->str() == "&")
|
||||
setFlag(fIsReference, true);
|
||||
}
|
||||
|
||||
if (_name)
|
||||
setFlag(fIsArray, arrayDimensions(_dimensions, _name->next()));
|
||||
if (_start)
|
||||
setFlag(fIsClass, !_start->isStandardType() && !isPointer() && !isReference());
|
||||
if (_access == Argument && _name) {
|
||||
const Token* tok = _name->next();
|
||||
while (tok->str() == "[")
|
||||
tok = tok->link();
|
||||
setFlag(fHasDefault, tok->str() == "=");
|
||||
}
|
||||
}
|
||||
|
||||
bool Function::argsMatch(const Scope *scope, const Token *first, const Token *second, const std::string &path, unsigned int depth)
|
||||
{
|
||||
while (first->str() == second->str()) {
|
||||
|
@ -1233,7 +1255,7 @@ void SymbolDatabase::debugMessage(const Token *tok, const std::string &msg) cons
|
|||
}
|
||||
}
|
||||
|
||||
bool SymbolDatabase::arrayDimensions(std::vector<Dimension> &dimensions, const Token *tok) const
|
||||
bool Variable::arrayDimensions(std::vector<Dimension> &dimensions, const Token *tok)
|
||||
{
|
||||
bool isArray = false;
|
||||
|
||||
|
@ -1524,18 +1546,12 @@ void Function::addArguments(const SymbolDatabase *symbolDatabase, const Scope *s
|
|||
const Token* startTok = tok;
|
||||
const Token* endTok = NULL;
|
||||
const Token* nameTok = NULL;
|
||||
bool isConstVar = bool(tok->str() == "const");
|
||||
bool isArrayVar = false;
|
||||
bool hasDefault = false;
|
||||
std::vector<Dimension> dimensions;
|
||||
|
||||
while (tok->str() != "," && tok->str() != ")" && tok->str() != "=") {
|
||||
if (tok->varId() != 0) {
|
||||
nameTok = tok;
|
||||
endTok = tok->previous();
|
||||
} else if (tok->str() == "[") {
|
||||
isArrayVar = symbolDatabase->arrayDimensions(dimensions, tok);
|
||||
|
||||
// skip array dimension(s)
|
||||
tok = tok->link();
|
||||
while (tok->next()->str() == "[")
|
||||
|
@ -1552,7 +1568,7 @@ void Function::addArguments(const SymbolDatabase *symbolDatabase, const Scope *s
|
|||
return;
|
||||
}
|
||||
|
||||
const Token *typeTok = startTok->tokAt(isConstVar ? 1 : 0);
|
||||
const Token *typeTok = startTok->tokAt(startTok->str() == "const" ? 1 : 0);
|
||||
if (typeTok->str() == "struct")
|
||||
typeTok = typeTok->next();
|
||||
|
||||
|
@ -1575,19 +1591,13 @@ void Function::addArguments(const SymbolDatabase *symbolDatabase, const Scope *s
|
|||
if (!typeTok->isStandardType())
|
||||
argType = symbolDatabase->findVariableType(scope, typeTok);
|
||||
|
||||
bool isClassVar = startTok == endTok && !startTok->isStandardType();
|
||||
bool isPointerVar = nameTok->strAt(-1) == "*" || nameTok->strAt(-2) == "*";
|
||||
bool isReferenceVar = nameTok->strAt(-1) == "&";
|
||||
|
||||
// skip default values
|
||||
if (tok->str() == "=") {
|
||||
hasDefault = true;
|
||||
|
||||
while (tok->str() != "," && tok->str() != ")")
|
||||
tok = tok->next();
|
||||
}
|
||||
|
||||
argumentList.push_back(Variable(nameTok, startTok, endTok, count++, Argument, false, false, isConstVar, isClassVar, argType, functionScope, isArrayVar, isPointerVar, isReferenceVar, hasDefault, dimensions));
|
||||
argumentList.push_back(Variable(nameTok, startTok, endTok, count++, Argument, argType, functionScope));
|
||||
|
||||
if (tok->str() == ")")
|
||||
break;
|
||||
|
@ -1883,56 +1893,38 @@ const Token *Scope::checkVariable(const Token *tok, AccessControl varaccess)
|
|||
}
|
||||
|
||||
// Is it const..?
|
||||
bool isConst(tok->str() == "const");
|
||||
if (isConst) {
|
||||
if (tok->str() == "const") {
|
||||
tok = tok->next();
|
||||
}
|
||||
|
||||
// Is it a static variable?
|
||||
const bool isStatic(tok->str() == "static");
|
||||
if (isStatic) {
|
||||
if (tok->str() == "static") {
|
||||
tok = tok->next();
|
||||
}
|
||||
|
||||
// Is it a mutable variable?
|
||||
const bool isMutable(tok->str() == "mutable");
|
||||
if (isMutable) {
|
||||
if (tok->str() == "mutable") {
|
||||
tok = tok->next();
|
||||
}
|
||||
|
||||
// Is it const..?
|
||||
if (tok->str() == "const") {
|
||||
tok = tok->next();
|
||||
isConst = true;
|
||||
}
|
||||
|
||||
// the start of the type tokens does not include the above modifiers
|
||||
const Token *typestart = tok;
|
||||
|
||||
bool isClass = false;
|
||||
|
||||
if (Token::Match(tok, "struct|union")) {
|
||||
tok = tok->next();
|
||||
}
|
||||
|
||||
bool isArray = false;
|
||||
bool isPointer = false;
|
||||
bool isReference = false;
|
||||
std::vector<Dimension> dimensions;
|
||||
|
||||
if (tok && isVariableDeclaration(tok, vartok, typetok, isArray, isPointer, isReference)) {
|
||||
isClass = (!typetok->isStandardType() && !isPointer && vartok->previous()->str() != "&");
|
||||
if (isArray) {
|
||||
isArray = check->arrayDimensions(dimensions, vartok->next());
|
||||
if (tok && isVariableDeclaration(tok, vartok, typetok)) {
|
||||
// If the vartok was set in the if-blocks above, create a entry for this variable..
|
||||
tok = vartok->next();
|
||||
while (tok && tok->str() == "[")
|
||||
tok = tok->link()->next();
|
||||
} else
|
||||
tok = vartok->next();
|
||||
}
|
||||
|
||||
// If the vartok was set in the if-blocks above, create a entry for this variable..
|
||||
if (vartok && vartok->str() != "operator") {
|
||||
if (vartok->varId() == 0 && !vartok->isBoolean())
|
||||
check->debugMessage(vartok, "Scope::checkVariable found variable \'" + vartok->str() + "\' with varid 0.");
|
||||
|
||||
|
@ -1941,7 +1933,7 @@ const Token *Scope::checkVariable(const Token *tok, AccessControl varaccess)
|
|||
if (typetok)
|
||||
scope = check->findVariableType(this, typetok);
|
||||
|
||||
addVariable(vartok, typestart, vartok->previous(), varaccess, isMutable, isStatic, isConst, isClass, scope, this, isArray, isPointer, isReference, dimensions);
|
||||
addVariable(vartok, typestart, vartok->previous(), varaccess, scope, this);
|
||||
}
|
||||
|
||||
return tok;
|
||||
|
@ -1980,7 +1972,7 @@ static const Token* skipPointers(const Token* tok)
|
|||
return tok;
|
||||
}
|
||||
|
||||
bool Scope::isVariableDeclaration(const Token* tok, const Token*& vartok, const Token*& typetok, bool &isArray, bool &isPointer, bool &isReference) const
|
||||
bool Scope::isVariableDeclaration(const Token* tok, const Token*& vartok, const Token*& typetok) const
|
||||
{
|
||||
if (tok && tok->str() == "throw" && check->_tokenizer->isCPP())
|
||||
return false;
|
||||
|
@ -2006,28 +1998,21 @@ bool Scope::isVariableDeclaration(const Token* tok, const Token*& vartok, const
|
|||
if (Token::Match(localVarTok, "%var% ;|=")) {
|
||||
vartok = localVarTok;
|
||||
typetok = localTypeTok;
|
||||
isArray = false;
|
||||
} else if (Token::Match(localVarTok, "%var% [") && localVarTok->str() != "operator") {
|
||||
vartok = localVarTok;
|
||||
typetok = localTypeTok;
|
||||
isArray = true;
|
||||
} else if ((isLocal() || type == Scope::eFunction) &&
|
||||
Token::Match(localVarTok, "%var% (") &&
|
||||
Token::simpleMatch(localVarTok->next()->link(), ") ;")) {
|
||||
vartok = localVarTok;
|
||||
typetok = localTypeTok;
|
||||
isArray = false;
|
||||
} else if (type == eCatch &&
|
||||
(Token::Match(localTypeTok, "%var% )") ||
|
||||
Token::Match(localTypeTok, "%var% &| %var% )"))) {
|
||||
vartok = localVarTok;
|
||||
typetok = localTypeTok;
|
||||
isArray = false;
|
||||
}
|
||||
|
||||
isPointer = vartok && (vartok->strAt(-1) == "*" || Token::simpleMatch(vartok->tokAt(-2), "* const"));
|
||||
isReference = vartok && vartok->strAt(-1) == "&";
|
||||
|
||||
return NULL != vartok;
|
||||
}
|
||||
|
||||
|
|
|
@ -84,12 +84,18 @@ class Variable {
|
|||
_flags = state_ ? _flags | flag_ : _flags & ~flag_;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief parse and save array dimension information
|
||||
* @param dimensions array dimensions vector
|
||||
* @param tok the first '[' token of array declaration
|
||||
* @return true if array, false if not
|
||||
*/
|
||||
static bool arrayDimensions(std::vector<Dimension> &dimensions, const Token *tok);
|
||||
|
||||
public:
|
||||
Variable(const Token *name_, const Token *start_, const Token *end_,
|
||||
std::size_t index_, AccessControl access_, bool mutable_,
|
||||
bool static_, bool const_, bool class_, const Scope *type_,
|
||||
const Scope *scope_, bool array_, bool pointer_, bool reference_,
|
||||
bool default_, const std::vector<Dimension> &dimensions_)
|
||||
std::size_t index_, AccessControl access_, const Scope *type_,
|
||||
const Scope *scope_)
|
||||
: _name(name_),
|
||||
_start(start_),
|
||||
_end(end_),
|
||||
|
@ -98,15 +104,7 @@ public:
|
|||
_flags(0),
|
||||
_type(type_),
|
||||
_scope(scope_) {
|
||||
setFlag(fIsMutable, mutable_);
|
||||
setFlag(fIsStatic, static_);
|
||||
setFlag(fIsConst, const_);
|
||||
setFlag(fIsClass, class_);
|
||||
setFlag(fIsArray, array_);
|
||||
setFlag(fIsPointer, pointer_);
|
||||
setFlag(fIsReference, reference_);
|
||||
setFlag(fHasDefault, default_);
|
||||
_dimensions = dimensions_;
|
||||
evaluate();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -354,6 +352,9 @@ private:
|
|||
|
||||
/** @brief array dimensions */
|
||||
std::vector<Dimension> _dimensions;
|
||||
|
||||
/** @brief fill in information, depending on Tokens given at instanciation */
|
||||
void evaluate();
|
||||
};
|
||||
|
||||
class Function {
|
||||
|
@ -384,7 +385,6 @@ public:
|
|||
std::size_t argCount() const {
|
||||
return argumentList.size();
|
||||
}
|
||||
/** @brief get a pointer to the variable instance associated with the given argument number */
|
||||
const Variable* getArgumentVar(unsigned int num) const;
|
||||
unsigned int initializedArgCount() const;
|
||||
void addArguments(const SymbolDatabase *symbolDatabase, const Scope *scope);
|
||||
|
@ -486,13 +486,11 @@ public:
|
|||
const Scope * findQualifiedScope(const std::string & name) const;
|
||||
|
||||
void addVariable(const Token *token_, const Token *start_,
|
||||
const Token *end_, AccessControl access_, bool mutable_,
|
||||
bool static_, bool const_, bool class_, const Scope *type_,
|
||||
const Scope *scope_, bool array_, bool pointer_, bool reference_,
|
||||
const std::vector<Dimension> &dimensions_) {
|
||||
const Token *end_, AccessControl access_, const Scope *type_,
|
||||
const Scope *scope_) {
|
||||
varlist.push_back(Variable(token_, start_, end_, varlist.size(),
|
||||
access_, mutable_, static_, const_, class_,
|
||||
type_, scope_, array_, pointer_, reference_, false, dimensions_));
|
||||
access_,
|
||||
type_, scope_));
|
||||
}
|
||||
|
||||
/** @brief initialize varlist */
|
||||
|
@ -537,7 +535,7 @@ private:
|
|||
* @param isPointer reference to variable to set if pointer is found
|
||||
* @return true if tok points to a variable declaration, false otherwise
|
||||
*/
|
||||
bool isVariableDeclaration(const Token* tok, const Token*& vartok, const Token*& typetok, bool &isArray, bool &isPointer, bool &isReference) const;
|
||||
bool isVariableDeclaration(const Token* tok, const Token*& vartok, const Token*& typetok) const;
|
||||
};
|
||||
|
||||
class SymbolDatabase {
|
||||
|
@ -578,14 +576,6 @@ public:
|
|||
*/
|
||||
void debugMessage(const Token *tok, const std::string &msg) const;
|
||||
|
||||
/**
|
||||
* @brief parse and save array dimension information
|
||||
* @param dimensions array dimensions vector
|
||||
* @param tok the first '[' token of array declaration
|
||||
* @return true if array, false if not
|
||||
*/
|
||||
bool arrayDimensions(std::vector<Dimension> &dimensions, const Token *tok) const;
|
||||
|
||||
void printOut(const char * title = NULL) const;
|
||||
void printVariable(const Variable *var, const char *indent) const;
|
||||
|
||||
|
|
|
@ -44,31 +44,21 @@ public:
|
|||
,vartok(NULL)
|
||||
,typetok(NULL)
|
||||
,t(NULL)
|
||||
,isArray(false)
|
||||
,isPointer(false)
|
||||
,isReference(false)
|
||||
,found(false)
|
||||
{}
|
||||
|
||||
virtual void reportOut(const std::string &outmsg) {
|
||||
errout << outmsg << std::endl;
|
||||
}
|
||||
|
||||
private:
|
||||
const Scope si;
|
||||
const Token* vartok;
|
||||
const Token* typetok;
|
||||
const Token* t;
|
||||
bool isArray;
|
||||
bool isPointer;
|
||||
bool isReference;
|
||||
bool found;
|
||||
|
||||
void reset() {
|
||||
vartok = NULL;
|
||||
typetok = NULL;
|
||||
t = NULL;
|
||||
isArray = false;
|
||||
isPointer = false;
|
||||
isReference = false;
|
||||
found = false;
|
||||
}
|
||||
|
||||
void run() {
|
||||
|
@ -157,287 +147,301 @@ private:
|
|||
|
||||
void test_isVariableDeclarationCanHandleNull() {
|
||||
reset();
|
||||
bool result = si.isVariableDeclaration(NULL, vartok, typetok, isArray, isPointer, isReference);
|
||||
bool result = si.isVariableDeclaration(NULL, vartok, typetok);
|
||||
ASSERT_EQUALS(false, result);
|
||||
ASSERT(NULL == vartok);
|
||||
ASSERT(NULL == typetok);
|
||||
ASSERT(false == isArray);
|
||||
ASSERT(false == isPointer);
|
||||
ASSERT(false == isReference);
|
||||
Variable v(NULL, NULL, NULL, 0, Public, 0, 0);
|
||||
}
|
||||
|
||||
void test_isVariableDeclarationIdentifiesSimpleDeclaration() {
|
||||
reset();
|
||||
givenACodeSampleToTokenize simpleDeclaration("int x;");
|
||||
bool result = si.isVariableDeclaration(simpleDeclaration.tokens(), vartok, typetok, isArray, isPointer, isReference);
|
||||
bool result = si.isVariableDeclaration(simpleDeclaration.tokens(), vartok, typetok);
|
||||
ASSERT_EQUALS(true, result);
|
||||
ASSERT_EQUALS("x", vartok->str());
|
||||
ASSERT_EQUALS("int", typetok->str());
|
||||
ASSERT(false == isArray);
|
||||
ASSERT(false == isPointer);
|
||||
ASSERT(false == isReference);
|
||||
Variable v(vartok, typetok, vartok->previous(), 0, Public, 0, 0);
|
||||
ASSERT(false == v.isArray());
|
||||
ASSERT(false == v.isPointer());
|
||||
ASSERT(false == v.isReference());
|
||||
}
|
||||
|
||||
void test_isVariableDeclarationIdentifiesScopedDeclaration() {
|
||||
reset();
|
||||
givenACodeSampleToTokenize ScopedDeclaration("::int x;");
|
||||
bool result = si.isVariableDeclaration(ScopedDeclaration.tokens(), vartok, typetok, isArray, isPointer, isReference);
|
||||
bool result = si.isVariableDeclaration(ScopedDeclaration.tokens(), vartok, typetok);
|
||||
ASSERT_EQUALS(true, result);
|
||||
ASSERT_EQUALS("x", vartok->str());
|
||||
ASSERT_EQUALS("int", typetok->str());
|
||||
ASSERT(false == isArray);
|
||||
ASSERT(false == isPointer);
|
||||
ASSERT(false == isReference);
|
||||
Variable v(vartok, typetok, vartok->previous(), 0, Public, 0, 0);
|
||||
ASSERT(false == v.isArray());
|
||||
ASSERT(false == v.isPointer());
|
||||
ASSERT(false == v.isReference());
|
||||
}
|
||||
|
||||
void test_isVariableDeclarationIdentifiesStdDeclaration() {
|
||||
reset();
|
||||
givenACodeSampleToTokenize StdDeclaration("std::string x;");
|
||||
bool result = si.isVariableDeclaration(StdDeclaration.tokens(), vartok, typetok, isArray, isPointer, isReference);
|
||||
bool result = si.isVariableDeclaration(StdDeclaration.tokens(), vartok, typetok);
|
||||
ASSERT_EQUALS(true, result);
|
||||
ASSERT_EQUALS("x", vartok->str());
|
||||
ASSERT_EQUALS("string", typetok->str());
|
||||
ASSERT(false == isArray);
|
||||
ASSERT(false == isPointer);
|
||||
ASSERT(false == isReference);
|
||||
Variable v(vartok, typetok, vartok->previous(), 0, Public, 0, 0);
|
||||
ASSERT(false == v.isArray());
|
||||
ASSERT(false == v.isPointer());
|
||||
ASSERT(false == v.isReference());
|
||||
}
|
||||
|
||||
void test_isVariableDeclarationIdentifiesScopedStdDeclaration() {
|
||||
reset();
|
||||
givenACodeSampleToTokenize StdDeclaration("::std::string x;");
|
||||
bool result = si.isVariableDeclaration(StdDeclaration.tokens(), vartok, typetok, isArray, isPointer, isReference);
|
||||
bool result = si.isVariableDeclaration(StdDeclaration.tokens(), vartok, typetok);
|
||||
ASSERT_EQUALS(true, result);
|
||||
ASSERT_EQUALS("x", vartok->str());
|
||||
ASSERT_EQUALS("string", typetok->str());
|
||||
ASSERT(false == isArray);
|
||||
ASSERT(false == isPointer);
|
||||
ASSERT(false == isReference);
|
||||
Variable v(vartok, typetok, vartok->previous(), 0, Public, 0, 0);
|
||||
ASSERT(false == v.isArray());
|
||||
ASSERT(false == v.isPointer());
|
||||
ASSERT(false == v.isReference());
|
||||
}
|
||||
|
||||
void test_isVariableDeclarationIdentifiesManyScopes() {
|
||||
reset();
|
||||
givenACodeSampleToTokenize manyScopes("AA::BB::CC::DD::EE x;");
|
||||
bool result = si.isVariableDeclaration(manyScopes.tokens(), vartok, typetok, isArray, isPointer, isReference);
|
||||
bool result = si.isVariableDeclaration(manyScopes.tokens(), vartok, typetok);
|
||||
ASSERT_EQUALS(true, result);
|
||||
ASSERT_EQUALS("x", vartok->str());
|
||||
ASSERT_EQUALS("EE", typetok->str());
|
||||
ASSERT(false == isArray);
|
||||
ASSERT(false == isPointer);
|
||||
ASSERT(false == isReference);
|
||||
Variable v(vartok, typetok, vartok->previous(), 0, Public, 0, 0);
|
||||
ASSERT(false == v.isArray());
|
||||
ASSERT(false == v.isPointer());
|
||||
ASSERT(false == v.isReference());
|
||||
}
|
||||
|
||||
void test_isVariableDeclarationIdentifiesPointers() {
|
||||
reset();
|
||||
givenACodeSampleToTokenize pointer("int* p;");
|
||||
bool result = si.isVariableDeclaration(pointer.tokens(), vartok, typetok, isArray, isPointer, isReference);
|
||||
bool result = si.isVariableDeclaration(pointer.tokens(), vartok, typetok);
|
||||
ASSERT_EQUALS(true, result);
|
||||
ASSERT_EQUALS("p", vartok->str());
|
||||
ASSERT_EQUALS("int", typetok->str());
|
||||
ASSERT(false == isArray);
|
||||
ASSERT(true == isPointer);
|
||||
ASSERT(false == isReference);
|
||||
Variable v(vartok, typetok, vartok->previous(), 0, Public, 0, 0);
|
||||
ASSERT(false == v.isArray());
|
||||
ASSERT(true == v.isPointer());
|
||||
ASSERT(false == v.isReference());
|
||||
}
|
||||
|
||||
void test_isVariableDeclarationDoesNotIdentifyConstness() {
|
||||
reset();
|
||||
givenACodeSampleToTokenize constness("const int* cp;");
|
||||
bool result = si.isVariableDeclaration(constness.tokens(), vartok, typetok, isArray, isPointer, isReference);
|
||||
bool result = si.isVariableDeclaration(constness.tokens(), vartok, typetok);
|
||||
ASSERT_EQUALS(false, result);
|
||||
ASSERT(NULL == vartok);
|
||||
ASSERT(NULL == typetok);
|
||||
ASSERT(false == isArray);
|
||||
ASSERT(false == isPointer);
|
||||
ASSERT(false == isReference);
|
||||
}
|
||||
|
||||
void test_isVariableDeclarationIdentifiesFirstOfManyVariables() {
|
||||
reset();
|
||||
givenACodeSampleToTokenize multipleDeclaration("int first, second;");
|
||||
bool result = si.isVariableDeclaration(multipleDeclaration.tokens(), vartok, typetok, isArray, isPointer, isReference);
|
||||
bool result = si.isVariableDeclaration(multipleDeclaration.tokens(), vartok, typetok);
|
||||
ASSERT_EQUALS(true, result);
|
||||
ASSERT_EQUALS("first", vartok->str());
|
||||
ASSERT_EQUALS("int", typetok->str());
|
||||
ASSERT(false == isArray);
|
||||
ASSERT(false == isPointer);
|
||||
ASSERT(false == isReference);
|
||||
Variable v(vartok, typetok, vartok->previous(), 0, Public, 0, 0);
|
||||
ASSERT(false == v.isArray());
|
||||
ASSERT(false == v.isPointer());
|
||||
ASSERT(false == v.isReference());
|
||||
}
|
||||
|
||||
void test_isVariableDeclarationIdentifiesScopedPointerDeclaration() {
|
||||
reset();
|
||||
givenACodeSampleToTokenize manyScopes("AA::BB::CC::DD::EE* p;");
|
||||
bool result = si.isVariableDeclaration(manyScopes.tokens(), vartok, typetok, isArray, isPointer, isReference);
|
||||
bool result = si.isVariableDeclaration(manyScopes.tokens(), vartok, typetok);
|
||||
ASSERT_EQUALS(true, result);
|
||||
ASSERT_EQUALS("p", vartok->str());
|
||||
ASSERT_EQUALS("EE", typetok->str());
|
||||
ASSERT(false == isArray);
|
||||
ASSERT(true == isPointer);
|
||||
ASSERT(false == isReference);
|
||||
Variable v(vartok, typetok, vartok->previous(), 0, Public, 0, 0);
|
||||
ASSERT(false == v.isArray());
|
||||
ASSERT(true == v.isPointer());
|
||||
ASSERT(false == v.isReference());
|
||||
}
|
||||
|
||||
void test_isVariableDeclarationIdentifiesDeclarationWithIndirection() {
|
||||
reset();
|
||||
givenACodeSampleToTokenize pointerToPointer("int** pp;");
|
||||
bool result = si.isVariableDeclaration(pointerToPointer.tokens(), vartok, typetok, isArray, isPointer, isReference);
|
||||
bool result = si.isVariableDeclaration(pointerToPointer.tokens(), vartok, typetok);
|
||||
ASSERT_EQUALS(true, result);
|
||||
ASSERT_EQUALS("pp", vartok->str());
|
||||
ASSERT_EQUALS("int", typetok->str());
|
||||
ASSERT(false == isArray);
|
||||
ASSERT(true == isPointer);
|
||||
ASSERT(false == isReference);
|
||||
Variable v(vartok, typetok, vartok->previous(), 0, Public, 0, 0);
|
||||
ASSERT(false == v.isArray());
|
||||
ASSERT(true == v.isPointer());
|
||||
ASSERT(false == v.isReference());
|
||||
}
|
||||
|
||||
void test_isVariableDeclarationIdentifiesDeclarationWithMultipleIndirection() {
|
||||
reset();
|
||||
givenACodeSampleToTokenize pointerToPointer("int***** p;");
|
||||
bool result = si.isVariableDeclaration(pointerToPointer.tokens(), vartok, typetok, isArray, isPointer, isReference);
|
||||
bool result = si.isVariableDeclaration(pointerToPointer.tokens(), vartok, typetok);
|
||||
ASSERT_EQUALS(true, result);
|
||||
ASSERT_EQUALS("p", vartok->str());
|
||||
ASSERT_EQUALS("int", typetok->str());
|
||||
ASSERT(false == isArray);
|
||||
ASSERT(true == isPointer);
|
||||
ASSERT(false == isReference);
|
||||
Variable v(vartok, typetok, vartok->previous(), 0, Public, 0, 0);
|
||||
ASSERT(false == v.isArray());
|
||||
ASSERT(true == v.isPointer());
|
||||
ASSERT(false == v.isReference());
|
||||
}
|
||||
|
||||
void test_isVariableDeclarationIdentifiesArray() {
|
||||
reset();
|
||||
givenACodeSampleToTokenize array("::std::string v[3];");
|
||||
bool result = si.isVariableDeclaration(array.tokens(), vartok, typetok, isArray, isPointer, isReference);
|
||||
bool result = si.isVariableDeclaration(array.tokens(), vartok, typetok);
|
||||
ASSERT_EQUALS(true, result);
|
||||
ASSERT_EQUALS("v", vartok->str());
|
||||
ASSERT_EQUALS("string", typetok->str());
|
||||
ASSERT(true == isArray);
|
||||
ASSERT(false == isPointer);
|
||||
ASSERT(false == isReference);
|
||||
Variable v(vartok, typetok, vartok->previous(), 0, Public, 0, 0);
|
||||
ASSERT(true == v.isArray());
|
||||
ASSERT(false == v.isPointer());
|
||||
ASSERT(false == v.isReference());
|
||||
}
|
||||
|
||||
void test_isVariableDeclarationIdentifiesOfArrayPointers() {
|
||||
reset();
|
||||
givenACodeSampleToTokenize array("A *a[5];");
|
||||
bool result = si.isVariableDeclaration(array.tokens(), vartok, typetok, isArray, isPointer, isReference);
|
||||
bool result = si.isVariableDeclaration(array.tokens(), vartok, typetok);
|
||||
ASSERT_EQUALS(true, result);
|
||||
ASSERT_EQUALS("a", vartok->str());
|
||||
ASSERT_EQUALS("A", typetok->str());
|
||||
ASSERT(true == isArray);
|
||||
ASSERT(true == isPointer);
|
||||
ASSERT(false == isReference);
|
||||
Variable v(vartok, typetok, vartok->previous(), 0, Public, 0, 0);
|
||||
ASSERT(true == v.isArray());
|
||||
ASSERT(true == v.isPointer());
|
||||
ASSERT(false == v.isReference());
|
||||
}
|
||||
|
||||
void isVariableDeclarationIdentifiesTemplatedPointerVariable() {
|
||||
reset();
|
||||
givenACodeSampleToTokenize var("std::set<char>* chars;");
|
||||
bool result = si.isVariableDeclaration(var.tokens(), vartok, typetok, isArray, isPointer, isReference);
|
||||
bool result = si.isVariableDeclaration(var.tokens(), vartok, typetok);
|
||||
ASSERT_EQUALS(true, result);
|
||||
ASSERT_EQUALS("chars", vartok->str());
|
||||
ASSERT_EQUALS("set", typetok->str());
|
||||
ASSERT(false == isArray);
|
||||
ASSERT(true == isPointer);
|
||||
ASSERT(false == isReference);
|
||||
Variable v(vartok, typetok, vartok->previous(), 0, Public, 0, 0);
|
||||
ASSERT(false == v.isArray());
|
||||
ASSERT(true == v.isPointer());
|
||||
ASSERT(false == v.isReference());
|
||||
}
|
||||
|
||||
void isVariableDeclarationIdentifiesTemplatedPointerToPointerVariable() {
|
||||
reset();
|
||||
givenACodeSampleToTokenize var("std::deque<int>*** ints;");
|
||||
bool result = si.isVariableDeclaration(var.tokens(), vartok, typetok, isArray, isPointer, isReference);
|
||||
bool result = si.isVariableDeclaration(var.tokens(), vartok, typetok);
|
||||
ASSERT_EQUALS(true, result);
|
||||
ASSERT_EQUALS("ints", vartok->str());
|
||||
ASSERT_EQUALS("deque", typetok->str());
|
||||
ASSERT(false == isArray);
|
||||
ASSERT(true == isPointer);
|
||||
ASSERT(false == isReference);
|
||||
Variable v(vartok, typetok, vartok->previous(), 0, Public, 0, 0);
|
||||
ASSERT(false == v.isArray());
|
||||
ASSERT(true == v.isPointer());
|
||||
ASSERT(false == v.isReference());
|
||||
}
|
||||
|
||||
void isVariableDeclarationIdentifiesTemplatedArrayVariable() {
|
||||
reset();
|
||||
givenACodeSampleToTokenize var("std::deque<int> ints[3];");
|
||||
bool result = si.isVariableDeclaration(var.tokens(), vartok, typetok, isArray, isPointer, isReference);
|
||||
bool result = si.isVariableDeclaration(var.tokens(), vartok, typetok);
|
||||
ASSERT_EQUALS(true, result);
|
||||
ASSERT_EQUALS("ints", vartok->str());
|
||||
ASSERT_EQUALS("deque", typetok->str());
|
||||
ASSERT(true == isArray);
|
||||
ASSERT(false == isPointer);
|
||||
ASSERT(false == isReference);
|
||||
Variable v(vartok, typetok, vartok->previous(), 0, Public, 0, 0);
|
||||
ASSERT(true == v.isArray());
|
||||
ASSERT(false == v.isPointer());
|
||||
ASSERT(false == v.isReference());
|
||||
}
|
||||
|
||||
void isVariableDeclarationIdentifiesTemplatedVariable() {
|
||||
reset();
|
||||
givenACodeSampleToTokenize var("std::vector<int> ints;");
|
||||
bool result = si.isVariableDeclaration(var.tokens(), vartok, typetok, isArray, isPointer, isReference);
|
||||
bool result = si.isVariableDeclaration(var.tokens(), vartok, typetok);
|
||||
ASSERT_EQUALS(true, result);
|
||||
ASSERT_EQUALS("ints", vartok->str());
|
||||
ASSERT_EQUALS("vector", typetok->str());
|
||||
ASSERT(false == isArray);
|
||||
ASSERT(false == isPointer);
|
||||
ASSERT(false == isReference);
|
||||
Variable v(vartok, typetok, vartok->previous(), 0, Public, 0, 0);
|
||||
ASSERT(false == v.isArray());
|
||||
ASSERT(false == v.isPointer());
|
||||
ASSERT(false == v.isReference());
|
||||
}
|
||||
|
||||
void isVariableDeclarationIdentifiesTemplatedVariableIterator() {
|
||||
reset();
|
||||
givenACodeSampleToTokenize var("std::list<int>::const_iterator floats;");
|
||||
bool result = si.isVariableDeclaration(var.tokens(), vartok, typetok, isArray, isPointer, isReference);
|
||||
bool result = si.isVariableDeclaration(var.tokens(), vartok, typetok);
|
||||
ASSERT_EQUALS(true, result);
|
||||
ASSERT_EQUALS("floats", vartok->str());
|
||||
ASSERT_EQUALS("const_iterator", typetok->str());
|
||||
ASSERT(false == isArray);
|
||||
ASSERT(false == isPointer);
|
||||
ASSERT(false == isReference);
|
||||
Variable v(vartok, typetok, vartok->previous(), 0, Public, 0, 0);
|
||||
ASSERT(false == v.isArray());
|
||||
ASSERT(false == v.isPointer());
|
||||
ASSERT(false == v.isReference());
|
||||
}
|
||||
|
||||
void isVariableDeclarationIdentifiesNestedTemplateVariable() {
|
||||
reset();
|
||||
givenACodeSampleToTokenize var("std::deque<std::set<int> > intsets;");
|
||||
bool result = si.isVariableDeclaration(var.tokens(), vartok, typetok, isArray, isPointer, isReference);
|
||||
bool result = si.isVariableDeclaration(var.tokens(), vartok, typetok);
|
||||
ASSERT_EQUALS(true, result);
|
||||
ASSERT_EQUALS("intsets", vartok->str());
|
||||
ASSERT_EQUALS("deque", typetok->str());
|
||||
ASSERT(false == isArray);
|
||||
ASSERT(false == isPointer);
|
||||
ASSERT(false == isReference);
|
||||
Variable v(vartok, typetok, vartok->previous(), 0, Public, 0, 0);
|
||||
ASSERT(false == v.isArray());
|
||||
ASSERT(false == v.isPointer());
|
||||
ASSERT(false == v.isReference());
|
||||
}
|
||||
|
||||
void isVariableDeclarationIdentifiesReference() {
|
||||
reset();
|
||||
givenACodeSampleToTokenize var1("int& foo;");
|
||||
bool result1 = si.isVariableDeclaration(var1.tokens(), vartok, typetok, isArray, isPointer, isReference);
|
||||
bool result1 = si.isVariableDeclaration(var1.tokens(), vartok, typetok);
|
||||
ASSERT_EQUALS(true, result1);
|
||||
ASSERT(false == isArray);
|
||||
ASSERT(false == isPointer);
|
||||
ASSERT(true == isReference);
|
||||
Variable v1(vartok, typetok, vartok->previous(), 0, Public, 0, 0);
|
||||
ASSERT(false == v1.isArray());
|
||||
ASSERT(false == v1.isPointer());
|
||||
ASSERT(true == v1.isReference());
|
||||
|
||||
reset();
|
||||
givenACodeSampleToTokenize var2("foo*& bar;");
|
||||
bool result2 = si.isVariableDeclaration(var2.tokens(), vartok, typetok, isArray, isPointer, isReference);
|
||||
bool result2 = si.isVariableDeclaration(var2.tokens(), vartok, typetok);
|
||||
ASSERT_EQUALS(true, result2);
|
||||
ASSERT(false == isArray);
|
||||
ASSERT(false == isPointer);
|
||||
ASSERT(true == isReference);
|
||||
Variable v2(vartok, typetok, vartok->previous(), 0, Public, 0, 0);
|
||||
ASSERT(false == v2.isArray());
|
||||
ASSERT(true == v2.isPointer());
|
||||
ASSERT(true == v2.isReference());
|
||||
|
||||
reset();
|
||||
givenACodeSampleToTokenize var3("std::vector<int>& foo;");
|
||||
bool result3 = si.isVariableDeclaration(var3.tokens(), vartok, typetok, isArray, isPointer, isReference);
|
||||
bool result3 = si.isVariableDeclaration(var3.tokens(), vartok, typetok);
|
||||
ASSERT_EQUALS(true, result3);
|
||||
ASSERT(false == isArray);
|
||||
ASSERT(false == isPointer);
|
||||
ASSERT(true == isReference);
|
||||
Variable v3(vartok, typetok, vartok->previous(), 0, Public, 0, 0);
|
||||
ASSERT(false == v3.isArray());
|
||||
ASSERT(false == v3.isPointer());
|
||||
ASSERT(true == v3.isReference());
|
||||
}
|
||||
|
||||
void isVariableDeclarationDoesNotIdentifyTemplateClass() {
|
||||
reset();
|
||||
givenACodeSampleToTokenize var("template <class T> class SomeClass{};");
|
||||
bool result = si.isVariableDeclaration(var.tokens(), vartok, typetok, isArray, isPointer, isReference);
|
||||
bool result = si.isVariableDeclaration(var.tokens(), vartok, typetok);
|
||||
ASSERT_EQUALS(false, result);
|
||||
ASSERT(false == isArray);
|
||||
ASSERT(false == isPointer);
|
||||
ASSERT(false == isReference);
|
||||
}
|
||||
|
||||
void isVariableDeclarationPointerConst() {
|
||||
reset();
|
||||
givenACodeSampleToTokenize var("std::string const* s;");
|
||||
bool result = si.isVariableDeclaration(var.tokens(), vartok, typetok, isArray, isPointer, isReference);
|
||||
bool result = si.isVariableDeclaration(var.tokens(), vartok, typetok);
|
||||
ASSERT_EQUALS(true, result);
|
||||
ASSERT(false == isArray);
|
||||
ASSERT(true == isPointer);
|
||||
ASSERT(false == isReference);
|
||||
Variable v(vartok, typetok, vartok->previous(), 0, Public, 0, 0);
|
||||
ASSERT(false == v.isArray());
|
||||
ASSERT(true == v.isPointer());
|
||||
ASSERT(false == v.isReference());
|
||||
}
|
||||
|
||||
void hasRegularFunction() {
|
||||
|
@ -450,12 +454,14 @@ private:
|
|||
const Scope *scope = db->findFunctionScopeByToken(tokenizer.tokens()->next());
|
||||
|
||||
ASSERT(scope && scope->className == "func");
|
||||
ASSERT(scope && scope->functionOf == 0);
|
||||
|
||||
const Function *function = db->findFunctionByToken(tokenizer.tokens()->next());
|
||||
|
||||
ASSERT(function && function->token->str() == "func");
|
||||
ASSERT(function && function->token == tokenizer.tokens()->next());
|
||||
ASSERT(function && function->hasBody);
|
||||
ASSERT(function && function->functionScope == scope && scope->function == function);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -469,12 +475,14 @@ private:
|
|||
const Scope *scope = db->findFunctionScopeByToken(tokenizer.tokens()->tokAt(4));
|
||||
|
||||
ASSERT(scope && scope->className == "func");
|
||||
ASSERT(scope && scope->functionOf && scope->functionOf == db->findScopeByName("Fred"));
|
||||
|
||||
const Function *function = db->findFunctionByToken(tokenizer.tokens()->tokAt(4));
|
||||
|
||||
ASSERT(function && function->token->str() == "func");
|
||||
ASSERT(function && function->token == tokenizer.tokens()->tokAt(4));
|
||||
ASSERT(function && function->hasBody && function->isInline);
|
||||
ASSERT(function && function->functionScope == scope && scope->function == function);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -507,12 +515,14 @@ private:
|
|||
const Scope *scope = db->findFunctionScopeByToken(tokenizer.tokens()->tokAt(12));
|
||||
|
||||
ASSERT(scope && scope->className == "func");
|
||||
ASSERT(scope && scope->functionOf && scope->functionOf == db->findScopeByName("Fred"));
|
||||
|
||||
const Function *function = db->findFunctionByToken(tokenizer.tokens()->tokAt(12));
|
||||
|
||||
ASSERT(function && function->token->str() == "func");
|
||||
ASSERT(function && function->token == tokenizer.tokens()->tokAt(12));
|
||||
ASSERT(function && function->hasBody && !function->isInline);
|
||||
ASSERT(function && function->functionScope == scope && scope->function == function);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -712,14 +722,27 @@ private:
|
|||
}
|
||||
|
||||
void functionArgs1() {
|
||||
check("void f(std::vector<std::string s>, const std::vector<int> & v) { }\n");
|
||||
|
||||
{
|
||||
GET_SYMBOL_DB("void f(std::vector<std::string>, const std::vector<int> & v) { }");
|
||||
TODO_ASSERT_EQUALS(1+1, 1+2, db->getVariableListSize());
|
||||
const Variable* v = db->getVariableFromVarId(2); // TODO: varId 1
|
||||
ASSERT(v && v->isReference() && v->isConst() && v->isArgument());
|
||||
const Scope* f = db->findScopeByName("f");
|
||||
ASSERT(f && f->type == Scope::eFunction && f->function);
|
||||
if (f && f->function)
|
||||
ASSERT(f->function->argumentList.size() == 2 && f->function->argumentList.front().index() == 0 && f->function->argumentList.front().name() == "" && f->function->argumentList.back().index() == 1);
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
check("void f(std::map<std::string, std::vector<int> > m) { }\n");
|
||||
|
||||
}
|
||||
{
|
||||
GET_SYMBOL_DB("void g(std::map<std::string, std::vector<int> > m) { }");
|
||||
ASSERT_EQUALS(1+1, db->getVariableListSize());
|
||||
const Variable* m = db->getVariableFromVarId(1);
|
||||
ASSERT(m && !m->isReference() && !m->isConst() && m->isArgument() && m->isClass());
|
||||
const Scope* g = db->findScopeByName("g");
|
||||
ASSERT(g && g->type == Scope::eFunction && g->function && g->function->argumentList.size() == 1 && g->function->argumentList.front().index() == 0);
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
}
|
||||
}
|
||||
|
||||
void functionArgs2() {
|
||||
GET_SYMBOL_DB("void f(int a[][4]) { }");
|
||||
|
|
Loading…
Reference in New Issue