Added support for references to symboldatabase

This commit is contained in:
PKEuS 2012-01-26 17:04:25 +01:00
parent 5c2af0b2e3
commit 6906001366
3 changed files with 109 additions and 41 deletions

View File

@ -107,7 +107,7 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti
// unnamed struct and union // unnamed struct and union
else if (Token::Match(tok, "struct|union {") && else if (Token::Match(tok, "struct|union {") &&
Token::Match(tok->next()->link(), "} |* %var% ;|[")) { Token::Match(tok->next()->link(), "} *|&| %var% ;|[")) {
scopeList.push_back(Scope(this, tok, scope)); scopeList.push_back(Scope(this, tok, scope));
Scope *new_scope = &scopeList.back(); Scope *new_scope = &scopeList.back();
@ -115,18 +115,22 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti
std::vector<Dimension> dimensions; std::vector<Dimension> dimensions;
bool isPointer = false; bool isPointer = false;
bool isReference = false;
bool isArray = false; bool isArray = false;
const Token* varNameTok = tok->next()->link()->next(); const Token* varNameTok = tok->next()->link()->next();
if (varNameTok->str() == "*") { if (varNameTok->str() == "*") {
isPointer = true; isPointer = true;
varNameTok = varNameTok->next(); varNameTok = varNameTok->next();
} else if (varNameTok->str() == "&") {
isReference = true;
varNameTok = varNameTok->next();
} }
if (varNameTok->next()->str() == "[") if (varNameTok->next()->str() == "[")
isArray = arrayDimensions(dimensions, varNameTok->next()); isArray = arrayDimensions(dimensions, varNameTok->next());
scope->addVariable(varNameTok, tok, tok, scope->access, false, false, false, true, new_scope, scope, isArray, isPointer, dimensions); scope->addVariable(varNameTok, tok, tok, scope->access, false, false, false, true, new_scope, scope, isArray, isPointer, isReference, dimensions);
const Token *tok2 = tok->next(); const Token *tok2 = tok->next();
@ -1281,6 +1285,7 @@ void SymbolDatabase::printVariable(const Variable *var, const char *indent) cons
std::cout << indent << " isClass: " << (var->isClass() ? "true" : "false") << std::endl; std::cout << indent << " isClass: " << (var->isClass() ? "true" : "false") << std::endl;
std::cout << indent << " isArray: " << (var->isArray() ? "true" : "false") << std::endl; std::cout << indent << " isArray: " << (var->isArray() ? "true" : "false") << std::endl;
std::cout << indent << " isPointer: " << (var->isPointer() ? "true" : "false") << std::endl; std::cout << indent << " isPointer: " << (var->isPointer() ? "true" : "false") << std::endl;
std::cout << indent << " isReference: " << (var->isReference() ? "true" : "false") << std::endl;
std::cout << indent << " hasDefault: " << (var->hasDefault() ? "true" : "false") << std::endl; std::cout << indent << " hasDefault: " << (var->hasDefault() ? "true" : "false") << std::endl;
std::cout << indent << "_type: "; std::cout << indent << "_type: ";
if (var->type()) { if (var->type()) {
@ -1557,6 +1562,7 @@ void Function::addArguments(const SymbolDatabase *symbolDatabase, const Function
bool isClassVar = startTok == endTok && !startTok->isStandardType(); bool isClassVar = startTok == endTok && !startTok->isStandardType();
bool isPointerVar = nameTok->strAt(-1) == "*" || nameTok->strAt(-2) == "*"; bool isPointerVar = nameTok->strAt(-1) == "*" || nameTok->strAt(-2) == "*";
bool isReferenceVar = nameTok->strAt(-1) == "&";
// skip default values // skip default values
if (tok->str() == "=") { if (tok->str() == "=") {
@ -1566,7 +1572,7 @@ void Function::addArguments(const SymbolDatabase *symbolDatabase, const Function
tok = tok->next(); tok = tok->next();
} }
argumentList.push_back(Variable(nameTok, startTok, endTok, count++, Argument, false, false, isConstVar, isClassVar, argType, functionScope, isArrayVar, isPointerVar, hasDefault, dimensions)); argumentList.push_back(Variable(nameTok, startTok, endTok, count++, Argument, false, false, isConstVar, isClassVar, argType, functionScope, isArrayVar, isPointerVar, isReferenceVar, hasDefault, dimensions));
if (tok->str() == ")") if (tok->str() == ")")
break; break;
@ -1830,10 +1836,10 @@ const Token *Scope::checkVariable(const Token *tok, AccessControl varaccess)
bool isArray = false; bool isArray = false;
bool isPointer = false; bool isPointer = false;
bool isReference = false;
std::vector<Dimension> dimensions; std::vector<Dimension> dimensions;
if (tok && isVariableDeclaration(tok, vartok, typetok, isArray, isPointer)) { if (tok && isVariableDeclaration(tok, vartok, typetok, isArray, isPointer, isReference)) {
isPointer = vartok->previous()->str() == "*" || Token::simpleMatch(vartok->tokAt(-2), "* const");
isClass = (!typetok->isStandardType() && !isPointer && vartok->previous()->str() != "&"); isClass = (!typetok->isStandardType() && !isPointer && vartok->previous()->str() != "&");
if (isArray) { if (isArray) {
isArray = check->arrayDimensions(dimensions, vartok->next()); isArray = check->arrayDimensions(dimensions, vartok->next());
@ -1854,7 +1860,7 @@ const Token *Scope::checkVariable(const Token *tok, AccessControl varaccess)
if (typetok) if (typetok)
scope = check->findVariableType(this, typetok); scope = check->findVariableType(this, typetok);
addVariable(vartok, typestart, vartok->previous(), varaccess, isMutable, isStatic, isConst, isClass, scope, this, isArray, isPointer, dimensions); addVariable(vartok, typestart, vartok->previous(), varaccess, isMutable, isStatic, isConst, isClass, scope, this, isArray, isPointer, isReference, dimensions);
} }
return tok; return tok;
@ -1897,7 +1903,7 @@ inline const Token* skipPointers(const Token* tok)
return ret; return ret;
} }
bool Scope::isVariableDeclaration(const Token* tok, const Token*& vartok, const Token*& typetok, bool &isArray, bool &isPointer) const bool Scope::isVariableDeclaration(const Token* tok, const Token*& vartok, const Token*& typetok, bool &isArray, bool &isPointer, bool &isReference) const
{ {
const Token* localTypeTok = skipScopeIdentifiers(tok); const Token* localTypeTok = skipScopeIdentifiers(tok);
const Token* localVarTok = NULL; const Token* localVarTok = NULL;
@ -1940,6 +1946,7 @@ bool Scope::isVariableDeclaration(const Token* tok, const Token*& vartok, const
} }
isPointer = vartok && (vartok->strAt(-1) == "*" || Token::simpleMatch(vartok->tokAt(-2), "* const")); isPointer = vartok && (vartok->strAt(-1) == "*" || Token::simpleMatch(vartok->tokAt(-2), "* const"));
isReference = vartok && vartok->strAt(-1) == "&";
return NULL != vartok; return NULL != vartok;
} }

View File

@ -56,13 +56,14 @@ struct Dimension {
class Variable { class Variable {
/** @brief flags mask used to access specific bit. */ /** @brief flags mask used to access specific bit. */
enum { enum {
fIsMutable = (1 << 0), /** @brief mutable variable */ fIsMutable = (1 << 0), /** @brief mutable variable */
fIsStatic = (1 << 1), /** @brief static variable */ fIsStatic = (1 << 1), /** @brief static variable */
fIsConst = (1 << 2), /** @brief const variable */ fIsConst = (1 << 2), /** @brief const variable */
fIsClass = (1 << 3), /** @brief user defined type */ fIsClass = (1 << 3), /** @brief user defined type */
fIsArray = (1 << 4), /** @brief array variable */ fIsArray = (1 << 4), /** @brief array variable */
fIsPointer = (1 << 5), /** @brief pointer variable */ fIsPointer = (1 << 5), /** @brief pointer variable */
fHasDefault = (1 << 6) /** @brief function argument with default value */ fIsReference = (1 << 6), /** @brief reference variable */
fHasDefault = (1 << 7) /** @brief function argument with default value */
}; };
/** /**
@ -87,8 +88,8 @@ public:
Variable(const Token *name_, const Token *start_, const Token *end_, Variable(const Token *name_, const Token *start_, const Token *end_,
std::size_t index_, AccessControl access_, bool mutable_, std::size_t index_, AccessControl access_, bool mutable_,
bool static_, bool const_, bool class_, const Scope *type_, bool static_, bool const_, bool class_, const Scope *type_,
const Scope *scope_, bool array_, bool pointer_, bool default_, const Scope *scope_, bool array_, bool pointer_, bool reference_,
const std::vector<Dimension> &dimensions_) bool default_, const std::vector<Dimension> &dimensions_)
: _name(name_), : _name(name_),
_start(start_), _start(start_),
_end(end_), _end(end_),
@ -103,6 +104,7 @@ public:
setFlag(fIsClass, class_); setFlag(fIsClass, class_);
setFlag(fIsArray, array_); setFlag(fIsArray, array_);
setFlag(fIsPointer, pointer_); setFlag(fIsPointer, pointer_);
setFlag(fIsReference, reference_);
setFlag(fHasDefault, default_); setFlag(fHasDefault, default_);
_dimensions = dimensions_; _dimensions = dimensions_;
} }
@ -270,13 +272,21 @@ public:
} }
/** /**
* Is pointer or array variable. * Is pointer variable.
* @return true if pointer, false otherwise * @return true if pointer, false otherwise
*/ */
bool isPointer() const { bool isPointer() const {
return getFlag(fIsPointer); return getFlag(fIsPointer);
} }
/**
* Is reference variable.
* @return true if reference, false otherwise
*/
bool isReference() const {
return getFlag(fIsReference);
}
/** /**
* Does variable have a default value. * Does variable have a default value.
* @return true if has a default falue, false if not * @return true if has a default falue, false if not
@ -469,11 +479,11 @@ public:
void addVariable(const Token *token_, const Token *start_, void addVariable(const Token *token_, const Token *start_,
const Token *end_, AccessControl access_, bool mutable_, const Token *end_, AccessControl access_, bool mutable_,
bool static_, bool const_, bool class_, const Scope *type_, bool static_, bool const_, bool class_, const Scope *type_,
const Scope *scope_, bool array_, bool pointer_, const Scope *scope_, bool array_, bool pointer_, bool reference_,
const std::vector<Dimension> &dimensions_) { const std::vector<Dimension> &dimensions_) {
varlist.push_back(Variable(token_, start_, end_, varlist.size(), varlist.push_back(Variable(token_, start_, end_, varlist.size(),
access_, mutable_, static_, const_, class_, access_, mutable_, static_, const_, class_,
type_, scope_, array_, pointer_, false, dimensions_)); type_, scope_, array_, pointer_, reference_, false, dimensions_));
} }
/** @brief initialize varlist */ /** @brief initialize varlist */
@ -518,7 +528,7 @@ private:
* @param isPointer reference to variable to set if pointer is found * @param isPointer reference to variable to set if pointer is found
* @return true if tok points to a variable declaration, false otherwise * @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) const; bool isVariableDeclaration(const Token* tok, const Token*& vartok, const Token*& typetok, bool &isArray, bool &isPointer, bool &isReference) const;
bool isSimpleVariable(const Token* tok) const; bool isSimpleVariable(const Token* tok) const;
bool isArrayVariable(const Token* tok) const; bool isArrayVariable(const Token* tok) const;
bool findClosingBracket(const Token* tok, const Token*& close) const; bool findClosingBracket(const Token* tok, const Token*& close) const;

View File

@ -39,6 +39,7 @@ public:
,found(false) ,found(false)
,isArray(false) ,isArray(false)
,isPointer(false) ,isPointer(false)
,isReference(false)
{} {}
virtual void reportOut(const std::string &outmsg) { virtual void reportOut(const std::string &outmsg) {
@ -53,6 +54,7 @@ private:
bool found; bool found;
bool isArray; bool isArray;
bool isPointer; bool isPointer;
bool isReference;
void reset() { void reset() {
vartok = NULL; vartok = NULL;
@ -61,6 +63,7 @@ private:
found = false; found = false;
isArray = false; isArray = false;
isPointer = false; isPointer = false;
isReference = false;
} }
void run() { void run() {
@ -84,6 +87,7 @@ private:
TEST_CASE(isVariableDeclarationIdentifiesTemplatedVariable); TEST_CASE(isVariableDeclarationIdentifiesTemplatedVariable);
TEST_CASE(isVariableDeclarationIdentifiesTemplatedVariableIterator); TEST_CASE(isVariableDeclarationIdentifiesTemplatedVariableIterator);
TEST_CASE(isVariableDeclarationIdentifiesNestedTemplateVariable); TEST_CASE(isVariableDeclarationIdentifiesNestedTemplateVariable);
TEST_CASE(isVariableDeclarationIdentifiesReference);
TEST_CASE(isVariableDeclarationDoesNotIdentifyTemplateClass); TEST_CASE(isVariableDeclarationDoesNotIdentifyTemplateClass);
TEST_CASE(canFindMatchingBracketsNeedsOpen); TEST_CASE(canFindMatchingBracketsNeedsOpen);
TEST_CASE(canFindMatchingBracketsInnerPair); TEST_CASE(canFindMatchingBracketsInnerPair);
@ -143,230 +147,277 @@ private:
void test_isVariableDeclarationCanHandleNull() { void test_isVariableDeclarationCanHandleNull() {
reset(); reset();
bool result = si.isVariableDeclaration(NULL, vartok, typetok, isArray, isPointer); bool result = si.isVariableDeclaration(NULL, vartok, typetok, isArray, isPointer, isReference);
ASSERT_EQUALS(false, result); ASSERT_EQUALS(false, result);
ASSERT(NULL == vartok); ASSERT(NULL == vartok);
ASSERT(NULL == typetok); ASSERT(NULL == typetok);
ASSERT(false == isArray); ASSERT(false == isArray);
ASSERT(false == isPointer); ASSERT(false == isPointer);
ASSERT(false == isReference);
} }
void test_isVariableDeclarationIdentifiesSimpleDeclaration() { void test_isVariableDeclarationIdentifiesSimpleDeclaration() {
reset(); reset();
givenACodeSampleToTokenize simpleDeclaration("int x;"); givenACodeSampleToTokenize simpleDeclaration("int x;");
bool result = si.isVariableDeclaration(simpleDeclaration.tokens(), vartok, typetok, isArray, isPointer); bool result = si.isVariableDeclaration(simpleDeclaration.tokens(), vartok, typetok, isArray, isPointer, isReference);
ASSERT_EQUALS(true, result); ASSERT_EQUALS(true, result);
ASSERT_EQUALS("x", vartok->str()); ASSERT_EQUALS("x", vartok->str());
ASSERT_EQUALS("int", typetok->str()); ASSERT_EQUALS("int", typetok->str());
ASSERT(false == isArray); ASSERT(false == isArray);
ASSERT(false == isPointer); ASSERT(false == isPointer);
ASSERT(false == isReference);
} }
void test_isVariableDeclarationIdentifiesScopedDeclaration() { void test_isVariableDeclarationIdentifiesScopedDeclaration() {
reset(); reset();
givenACodeSampleToTokenize ScopedDeclaration("::int x;"); givenACodeSampleToTokenize ScopedDeclaration("::int x;");
bool result = si.isVariableDeclaration(ScopedDeclaration.tokens(), vartok, typetok, isArray, isPointer); bool result = si.isVariableDeclaration(ScopedDeclaration.tokens(), vartok, typetok, isArray, isPointer, isReference);
ASSERT_EQUALS(true, result); ASSERT_EQUALS(true, result);
ASSERT_EQUALS("x", vartok->str()); ASSERT_EQUALS("x", vartok->str());
ASSERT_EQUALS("int", typetok->str()); ASSERT_EQUALS("int", typetok->str());
ASSERT(false == isArray); ASSERT(false == isArray);
ASSERT(false == isPointer); ASSERT(false == isPointer);
ASSERT(false == isReference);
} }
void test_isVariableDeclarationIdentifiesStdDeclaration() { void test_isVariableDeclarationIdentifiesStdDeclaration() {
reset(); reset();
givenACodeSampleToTokenize StdDeclaration("std::string x;"); givenACodeSampleToTokenize StdDeclaration("std::string x;");
bool result = si.isVariableDeclaration(StdDeclaration.tokens(), vartok, typetok, isArray, isPointer); bool result = si.isVariableDeclaration(StdDeclaration.tokens(), vartok, typetok, isArray, isPointer, isReference);
ASSERT_EQUALS(true, result); ASSERT_EQUALS(true, result);
ASSERT_EQUALS("x", vartok->str()); ASSERT_EQUALS("x", vartok->str());
ASSERT_EQUALS("string", typetok->str()); ASSERT_EQUALS("string", typetok->str());
ASSERT(false == isArray); ASSERT(false == isArray);
ASSERT(false == isPointer); ASSERT(false == isPointer);
ASSERT(false == isReference);
} }
void test_isVariableDeclarationIdentifiesScopedStdDeclaration() { void test_isVariableDeclarationIdentifiesScopedStdDeclaration() {
reset(); reset();
givenACodeSampleToTokenize StdDeclaration("::std::string x;"); givenACodeSampleToTokenize StdDeclaration("::std::string x;");
bool result = si.isVariableDeclaration(StdDeclaration.tokens(), vartok, typetok, isArray, isPointer); bool result = si.isVariableDeclaration(StdDeclaration.tokens(), vartok, typetok, isArray, isPointer, isReference);
ASSERT_EQUALS(true, result); ASSERT_EQUALS(true, result);
ASSERT_EQUALS("x", vartok->str()); ASSERT_EQUALS("x", vartok->str());
ASSERT_EQUALS("string", typetok->str()); ASSERT_EQUALS("string", typetok->str());
ASSERT(false == isArray); ASSERT(false == isArray);
ASSERT(false == isPointer); ASSERT(false == isPointer);
ASSERT(false == isReference);
} }
void test_isVariableDeclarationIdentifiesManyScopes() { void test_isVariableDeclarationIdentifiesManyScopes() {
reset(); reset();
givenACodeSampleToTokenize manyScopes("AA::BB::CC::DD::EE x;"); givenACodeSampleToTokenize manyScopes("AA::BB::CC::DD::EE x;");
bool result = si.isVariableDeclaration(manyScopes.tokens(), vartok, typetok, isArray, isPointer); bool result = si.isVariableDeclaration(manyScopes.tokens(), vartok, typetok, isArray, isPointer, isReference);
ASSERT_EQUALS(true, result); ASSERT_EQUALS(true, result);
ASSERT_EQUALS("x", vartok->str()); ASSERT_EQUALS("x", vartok->str());
ASSERT_EQUALS("EE", typetok->str()); ASSERT_EQUALS("EE", typetok->str());
ASSERT(false == isArray); ASSERT(false == isArray);
ASSERT(false == isPointer); ASSERT(false == isPointer);
ASSERT(false == isReference);
} }
void test_isVariableDeclarationIdentifiesPointers() { void test_isVariableDeclarationIdentifiesPointers() {
reset(); reset();
givenACodeSampleToTokenize pointer("int* p;"); givenACodeSampleToTokenize pointer("int* p;");
bool result = si.isVariableDeclaration(pointer.tokens(), vartok, typetok, isArray, isPointer); bool result = si.isVariableDeclaration(pointer.tokens(), vartok, typetok, isArray, isPointer, isReference);
ASSERT_EQUALS(true, result); ASSERT_EQUALS(true, result);
ASSERT_EQUALS("p", vartok->str()); ASSERT_EQUALS("p", vartok->str());
ASSERT_EQUALS("int", typetok->str()); ASSERT_EQUALS("int", typetok->str());
ASSERT(false == isArray); ASSERT(false == isArray);
ASSERT(true == isPointer); ASSERT(true == isPointer);
ASSERT(false == isReference);
} }
void test_isVariableDeclarationDoesNotIdentifyConstness() { void test_isVariableDeclarationDoesNotIdentifyConstness() {
reset(); reset();
givenACodeSampleToTokenize constness("const int* cp;"); givenACodeSampleToTokenize constness("const int* cp;");
bool result = si.isVariableDeclaration(constness.tokens(), vartok, typetok, isArray, isPointer); bool result = si.isVariableDeclaration(constness.tokens(), vartok, typetok, isArray, isPointer, isReference);
ASSERT_EQUALS(false, result); ASSERT_EQUALS(false, result);
ASSERT(NULL == vartok); ASSERT(NULL == vartok);
ASSERT(NULL == typetok); ASSERT(NULL == typetok);
ASSERT(false == isArray); ASSERT(false == isArray);
ASSERT(false == isPointer); ASSERT(false == isPointer);
ASSERT(false == isReference);
} }
void test_isVariableDeclarationIdentifiesFirstOfManyVariables() { void test_isVariableDeclarationIdentifiesFirstOfManyVariables() {
reset(); reset();
givenACodeSampleToTokenize multipleDeclaration("int first, second;"); givenACodeSampleToTokenize multipleDeclaration("int first, second;");
bool result = si.isVariableDeclaration(multipleDeclaration.tokens(), vartok, typetok, isArray, isPointer); bool result = si.isVariableDeclaration(multipleDeclaration.tokens(), vartok, typetok, isArray, isPointer, isReference);
ASSERT_EQUALS(true, result); ASSERT_EQUALS(true, result);
ASSERT_EQUALS("first", vartok->str()); ASSERT_EQUALS("first", vartok->str());
ASSERT_EQUALS("int", typetok->str()); ASSERT_EQUALS("int", typetok->str());
ASSERT(false == isArray); ASSERT(false == isArray);
ASSERT(false == isPointer); ASSERT(false == isPointer);
ASSERT(false == isReference);
} }
void test_isVariableDeclarationIdentifiesScopedPointerDeclaration() { void test_isVariableDeclarationIdentifiesScopedPointerDeclaration() {
reset(); reset();
givenACodeSampleToTokenize manyScopes("AA::BB::CC::DD::EE* p;"); givenACodeSampleToTokenize manyScopes("AA::BB::CC::DD::EE* p;");
bool result = si.isVariableDeclaration(manyScopes.tokens(), vartok, typetok, isArray, isPointer); bool result = si.isVariableDeclaration(manyScopes.tokens(), vartok, typetok, isArray, isPointer, isReference);
ASSERT_EQUALS(true, result); ASSERT_EQUALS(true, result);
ASSERT_EQUALS("p", vartok->str()); ASSERT_EQUALS("p", vartok->str());
ASSERT_EQUALS("EE", typetok->str()); ASSERT_EQUALS("EE", typetok->str());
ASSERT(false == isArray); ASSERT(false == isArray);
ASSERT(true == isPointer); ASSERT(true == isPointer);
ASSERT(false == isReference);
} }
void test_isVariableDeclarationIdentifiesDeclarationWithIndirection() { void test_isVariableDeclarationIdentifiesDeclarationWithIndirection() {
reset(); reset();
givenACodeSampleToTokenize pointerToPointer("int** pp;"); givenACodeSampleToTokenize pointerToPointer("int** pp;");
bool result = si.isVariableDeclaration(pointerToPointer.tokens(), vartok, typetok, isArray, isPointer); bool result = si.isVariableDeclaration(pointerToPointer.tokens(), vartok, typetok, isArray, isPointer, isReference);
ASSERT_EQUALS(true, result); ASSERT_EQUALS(true, result);
ASSERT_EQUALS("pp", vartok->str()); ASSERT_EQUALS("pp", vartok->str());
ASSERT_EQUALS("int", typetok->str()); ASSERT_EQUALS("int", typetok->str());
ASSERT(false == isArray); ASSERT(false == isArray);
ASSERT(true == isPointer); ASSERT(true == isPointer);
ASSERT(false == isReference);
} }
void test_isVariableDeclarationIdentifiesDeclarationWithMultipleIndirection() { void test_isVariableDeclarationIdentifiesDeclarationWithMultipleIndirection() {
reset(); reset();
givenACodeSampleToTokenize pointerToPointer("int***** p;"); givenACodeSampleToTokenize pointerToPointer("int***** p;");
bool result = si.isVariableDeclaration(pointerToPointer.tokens(), vartok, typetok, isArray, isPointer); bool result = si.isVariableDeclaration(pointerToPointer.tokens(), vartok, typetok, isArray, isPointer, isReference);
ASSERT_EQUALS(true, result); ASSERT_EQUALS(true, result);
ASSERT_EQUALS("p", vartok->str()); ASSERT_EQUALS("p", vartok->str());
ASSERT_EQUALS("int", typetok->str()); ASSERT_EQUALS("int", typetok->str());
ASSERT(false == isArray); ASSERT(false == isArray);
ASSERT(true == isPointer); ASSERT(true == isPointer);
ASSERT(false == isReference);
} }
void test_isVariableDeclarationIdentifiesArray() { void test_isVariableDeclarationIdentifiesArray() {
reset(); reset();
givenACodeSampleToTokenize array("::std::string v[3];"); givenACodeSampleToTokenize array("::std::string v[3];");
bool result = si.isVariableDeclaration(array.tokens(), vartok, typetok, isArray, isPointer); bool result = si.isVariableDeclaration(array.tokens(), vartok, typetok, isArray, isPointer, isReference);
ASSERT_EQUALS(true, result); ASSERT_EQUALS(true, result);
ASSERT_EQUALS("v", vartok->str()); ASSERT_EQUALS("v", vartok->str());
ASSERT_EQUALS("string", typetok->str()); ASSERT_EQUALS("string", typetok->str());
ASSERT(true == isArray); ASSERT(true == isArray);
ASSERT(false == isPointer); ASSERT(false == isPointer);
ASSERT(false == isReference);
} }
void test_isVariableDeclarationIdentifiesOfArrayPointers() { void test_isVariableDeclarationIdentifiesOfArrayPointers() {
reset(); reset();
givenACodeSampleToTokenize array("A *a[5];"); givenACodeSampleToTokenize array("A *a[5];");
bool result = si.isVariableDeclaration(array.tokens(), vartok, typetok, isArray, isPointer); bool result = si.isVariableDeclaration(array.tokens(), vartok, typetok, isArray, isPointer, isReference);
ASSERT_EQUALS(true, result); ASSERT_EQUALS(true, result);
ASSERT_EQUALS("a", vartok->str()); ASSERT_EQUALS("a", vartok->str());
ASSERT_EQUALS("A", typetok->str()); ASSERT_EQUALS("A", typetok->str());
ASSERT(true == isArray); ASSERT(true == isArray);
ASSERT(true == isPointer); ASSERT(true == isPointer);
ASSERT(false == isReference);
} }
void isVariableDeclarationIdentifiesTemplatedPointerVariable() { void isVariableDeclarationIdentifiesTemplatedPointerVariable() {
reset(); reset();
givenACodeSampleToTokenize var("std::set<char>* chars;"); givenACodeSampleToTokenize var("std::set<char>* chars;");
bool result = si.isVariableDeclaration(var.tokens(), vartok, typetok, isArray, isPointer); bool result = si.isVariableDeclaration(var.tokens(), vartok, typetok, isArray, isPointer, isReference);
ASSERT_EQUALS(true, result); ASSERT_EQUALS(true, result);
ASSERT_EQUALS("chars", vartok->str()); ASSERT_EQUALS("chars", vartok->str());
ASSERT_EQUALS("set", typetok->str()); ASSERT_EQUALS("set", typetok->str());
ASSERT(false == isArray); ASSERT(false == isArray);
ASSERT(true == isPointer); ASSERT(true == isPointer);
ASSERT(false == isReference);
} }
void isVariableDeclarationIdentifiesTemplatedPointerToPointerVariable() { void isVariableDeclarationIdentifiesTemplatedPointerToPointerVariable() {
reset(); reset();
givenACodeSampleToTokenize var("std::deque<int>*** ints;"); givenACodeSampleToTokenize var("std::deque<int>*** ints;");
bool result = si.isVariableDeclaration(var.tokens(), vartok, typetok, isArray, isPointer); bool result = si.isVariableDeclaration(var.tokens(), vartok, typetok, isArray, isPointer, isReference);
ASSERT_EQUALS(true, result); ASSERT_EQUALS(true, result);
ASSERT_EQUALS("ints", vartok->str()); ASSERT_EQUALS("ints", vartok->str());
ASSERT_EQUALS("deque", typetok->str()); ASSERT_EQUALS("deque", typetok->str());
ASSERT(false == isArray); ASSERT(false == isArray);
ASSERT(true == isPointer); ASSERT(true == isPointer);
ASSERT(false == isReference);
} }
void isVariableDeclarationIdentifiesTemplatedArrayVariable() { void isVariableDeclarationIdentifiesTemplatedArrayVariable() {
reset(); reset();
givenACodeSampleToTokenize var("std::deque<int> ints[3];"); givenACodeSampleToTokenize var("std::deque<int> ints[3];");
bool result = si.isVariableDeclaration(var.tokens(), vartok, typetok, isArray, isPointer); bool result = si.isVariableDeclaration(var.tokens(), vartok, typetok, isArray, isPointer, isReference);
ASSERT_EQUALS(true, result); ASSERT_EQUALS(true, result);
ASSERT_EQUALS("ints", vartok->str()); ASSERT_EQUALS("ints", vartok->str());
ASSERT_EQUALS("deque", typetok->str()); ASSERT_EQUALS("deque", typetok->str());
ASSERT(true == isArray); ASSERT(true == isArray);
ASSERT(false == isPointer); ASSERT(false == isPointer);
ASSERT(false == isReference);
} }
void isVariableDeclarationIdentifiesTemplatedVariable() { void isVariableDeclarationIdentifiesTemplatedVariable() {
reset(); reset();
givenACodeSampleToTokenize var("std::vector<int> ints;"); givenACodeSampleToTokenize var("std::vector<int> ints;");
bool result = si.isVariableDeclaration(var.tokens(), vartok, typetok, isArray, isPointer); bool result = si.isVariableDeclaration(var.tokens(), vartok, typetok, isArray, isPointer, isReference);
ASSERT_EQUALS(true, result); ASSERT_EQUALS(true, result);
ASSERT_EQUALS("ints", vartok->str()); ASSERT_EQUALS("ints", vartok->str());
ASSERT_EQUALS("vector", typetok->str()); ASSERT_EQUALS("vector", typetok->str());
ASSERT(false == isArray); ASSERT(false == isArray);
ASSERT(false == isPointer); ASSERT(false == isPointer);
ASSERT(false == isReference);
} }
void isVariableDeclarationIdentifiesTemplatedVariableIterator() { void isVariableDeclarationIdentifiesTemplatedVariableIterator() {
reset(); reset();
givenACodeSampleToTokenize var("std::list<int>::const_iterator floats;"); givenACodeSampleToTokenize var("std::list<int>::const_iterator floats;");
bool result = si.isVariableDeclaration(var.tokens(), vartok, typetok, isArray, isPointer); bool result = si.isVariableDeclaration(var.tokens(), vartok, typetok, isArray, isPointer, isReference);
ASSERT_EQUALS(true, result); ASSERT_EQUALS(true, result);
ASSERT_EQUALS("floats", vartok->str()); ASSERT_EQUALS("floats", vartok->str());
ASSERT_EQUALS("const_iterator", typetok->str()); ASSERT_EQUALS("const_iterator", typetok->str());
ASSERT(false == isArray); ASSERT(false == isArray);
ASSERT(false == isPointer); ASSERT(false == isPointer);
ASSERT(false == isReference);
} }
void isVariableDeclarationIdentifiesNestedTemplateVariable() { void isVariableDeclarationIdentifiesNestedTemplateVariable() {
reset(); reset();
givenACodeSampleToTokenize var("std::deque<std::set<int> > intsets;"); givenACodeSampleToTokenize var("std::deque<std::set<int> > intsets;");
bool result = si.isVariableDeclaration(var.tokens(), vartok, typetok, isArray, isPointer); bool result = si.isVariableDeclaration(var.tokens(), vartok, typetok, isArray, isPointer, isReference);
ASSERT_EQUALS(true, result); ASSERT_EQUALS(true, result);
ASSERT_EQUALS("intsets", vartok->str()); ASSERT_EQUALS("intsets", vartok->str());
ASSERT_EQUALS("deque", typetok->str()); ASSERT_EQUALS("deque", typetok->str());
ASSERT(false == isArray); ASSERT(false == isArray);
ASSERT(false == isPointer); ASSERT(false == isPointer);
ASSERT(false == isReference);
}
void isVariableDeclarationIdentifiesReference() {
reset();
givenACodeSampleToTokenize var1("int& foo;");
bool result1 = si.isVariableDeclaration(var1.tokens(), vartok, typetok, isArray, isPointer, isReference);
ASSERT_EQUALS(true, result1);
ASSERT(false == isArray);
ASSERT(false == isPointer);
ASSERT(true == isReference);
reset();
givenACodeSampleToTokenize var2("foo*& bar;");
bool result2 = si.isVariableDeclaration(var2.tokens(), vartok, typetok, isArray, isPointer, isReference);
ASSERT_EQUALS(true, result2);
ASSERT(false == isArray);
ASSERT(false == isPointer);
ASSERT(true == isReference);
reset();
givenACodeSampleToTokenize var3("std::vector<int>& foo;");
bool result3 = si.isVariableDeclaration(var3.tokens(), vartok, typetok, isArray, isPointer, isReference);
ASSERT_EQUALS(true, result3);
ASSERT(false == isArray);
ASSERT(false == isPointer);
ASSERT(true == isReference);
} }
void isVariableDeclarationDoesNotIdentifyTemplateClass() { void isVariableDeclarationDoesNotIdentifyTemplateClass() {
reset(); reset();
givenACodeSampleToTokenize var("template <class T> class SomeClass{};"); givenACodeSampleToTokenize var("template <class T> class SomeClass{};");
bool result = si.isVariableDeclaration(var.tokens(), vartok, typetok, isArray, isPointer); bool result = si.isVariableDeclaration(var.tokens(), vartok, typetok, isArray, isPointer, isReference);
ASSERT_EQUALS(false, result); ASSERT_EQUALS(false, result);
ASSERT(false == isArray); ASSERT(false == isArray);
ASSERT(false == isPointer); ASSERT(false == isPointer);
ASSERT(false == isReference);
} }
void canFindMatchingBracketsNeedsOpen() { void canFindMatchingBracketsNeedsOpen() {