|
From: <net...@us...> - 2003-05-15 16:25:45
|
Update of /cvsroot/cpptool/rfta/src/rfta
In directory sc8-pr-cvs1:/tmp/cvs-serv15701/src/rfta
Added Files:
IdentifierScopeTest.h IdentifierScopeTest.cpp
IdentifierScope.h IdentifierScope.cpp
Log Message:
-- class to support identifier resolve within name scope and class scope
--- NEW FILE: IdentifierScopeTest.h ---
// //////////////////////////////////////////////////////////////////////////
// (c)Copyright 2003, Andre Baresel.
// Created: 2003/05/14
// //////////////////////////////////////////////////////////////////////////
#ifndef RFTA_IDENTIFIERSCOPETEST_H
#define RFTA_IDENTIFIERSCOPETEST_H
#include "IdentifierScope.h"
#include "UnitTesting.h"
namespace Refactoring
{
/// Unit tests for IdentifierScopeTest
class IdentifierScopeTest : public CppUnit::TestFixture
{
CPPUNIT_TEST_SUITE( IdentifierScopeTest );
CPPUNIT_TEST( testIdentifierResolutionInOneScope );
CPPUNIT_TEST_SUITE_END();
public:
/*! Constructs a IdentifierScopeTest object.
*/
IdentifierScopeTest();
/// Destructor.
virtual ~IdentifierScopeTest();
void setUp();
void tearDown();
void testIdentifierResolutionInOneScope();
};
// Inlines methods for IdentifierScopeTest:
// --------------------------------------------------
} // namespace Refactoring
#endif // RFTA_IDENTIFIERSCOPETEST_H
--- NEW FILE: IdentifierScopeTest.cpp ---
// //////////////////////////////////////////////////////////////////////////
// (c)Copyright 2003, Andre Baresel.
// Created: 2003/05/14
// //////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "IdentifierScopeTest.h"
#include <boost/weak_ptr.hpp>
#include <rfta/parser/SourceASTNode.h>
#include <rfta/parser/ASTNodes.h>
namespace Refactoring
{
RFTA_TEST_SUITE_REGISTRATION( IdentifierScopeTest );
IdentifierScopeTest::IdentifierScopeTest()
{
}
IdentifierScopeTest::~IdentifierScopeTest()
{
}
void
IdentifierScopeTest::setUp()
{
}
void
IdentifierScopeTest::tearDown()
{
}
void
IdentifierScopeTest::testIdentifierResolutionInOneScope()
{
IdentifierScopePtr rootScope = IdentifierScope::createScope(IdentifierScopeWeakPtr());
IdentifierScopePtr scopeA = IdentifierScope::createSubScope(rootScope,"A");
CPPUNIT_ASSERT_MESSAGE( "Expected a valid root scope.", bool(rootScope) );
CPPUNIT_ASSERT_MESSAGE( "Expected a valid sub scope.", bool(scopeA) );
CPPUNIT_ASSERT_MESSAGE( "Subscope registration wrong.", scopeA == rootScope->getSubScope("A") );
ASTNodePtr nodeB = ASTNode::create(ASTNodeTypes::variableIdentifier,ASTNodeWeakPtr(),0,0,SourceASTNodeWeakPtr());
ASTNodePtr nodeC = ASTNode::create(ASTNodeTypes::variableIdentifier,ASTNodeWeakPtr(),0,0,SourceASTNodeWeakPtr());
rootScope->addIdentifierDeclaration("C",nodeC);
scopeA ->addIdentifierDeclaration("B",nodeB);
try {
ASTNodePtr decl = rootScope->getIdentifierDeclaration("C");
CPPUNIT_ASSERT_MESSAGE( "Expected a AST node.", bool(decl) );
CPPUNIT_ASSERT_EQUAL_MESSAGE ( "Expect a different AST node. (memory adress)", nodeC , decl );
decl = scopeA->getIdentifierDeclaration("::C");
CPPUNIT_ASSERT_MESSAGE( "Expected a AST node.", bool(decl) );
CPPUNIT_ASSERT_EQUAL_MESSAGE ( "Expect a different AST node. (memory adress)", nodeC , decl );
decl = scopeA->getIdentifierDeclaration("B");
CPPUNIT_ASSERT_MESSAGE( "Expected a AST node.", bool(decl) );
CPPUNIT_ASSERT_EQUAL_MESSAGE ( "Expect a different AST node. (memory adress)", nodeB , decl );
decl = rootScope->getIdentifierDeclaration("A::B");
CPPUNIT_ASSERT_MESSAGE( "Expected a AST node.", bool(decl) );
CPPUNIT_ASSERT_EQUAL_MESSAGE ( "Expect a different AST node. (memory adress)", nodeB , decl );
decl = scopeA->getIdentifierDeclaration("::A::B");
CPPUNIT_ASSERT_MESSAGE( "Expected a AST node.", bool(decl) );
CPPUNIT_ASSERT_EQUAL_MESSAGE ( "Expect a different AST node. (memory adress)", nodeB , decl );
}
catch (IdentifierScopeException ex)
{
CPPUNIT_ASSERT_MESSAGE( std::string("Did not expect the following exception: ") + ex.what() , false );
}
}
} // namespace Refactoring
--- NEW FILE: IdentifierScope.h ---
// //////////////////////////////////////////////////////////////////////////
// (c)Copyright 2003, Andre Baresel.
// Created: 2003/05/13
// //////////////////////////////////////////////////////////////////////////
#ifndef RFTA_IDENTIFIERSCOPE_H
#define RFTA_IDENTIFIERSCOPE_H
#include <rfta/parser/SourceASTNode.h>
namespace Refactoring
{
class IdentifierScope;
typedef boost::shared_ptr<IdentifierScope> IdentifierScopePtr;
typedef boost::weak_ptr<IdentifierScope> IdentifierScopeWeakPtr;
class IdentifierScopeException: public std::exception
{
public:
enum ExceptionType {
InvalidScope = 1,
InvalidIdentifierName,
WrongQualifiedIdentifier,
IdentifierDeclaredTwice
};
IdentifierScopeException(ExceptionType reason);
virtual const char *what() const;
private:
ExceptionType reason_;
};
/// objects of this class store identifier scopes and sub scopes
/// (identifier visibility, top level is file scope).
class IdentifierScope
{
public:
static IdentifierScopePtr createScope(IdentifierScopeWeakPtr parent);
static IdentifierScopePtr createSubScope(IdentifierScopeWeakPtr parent, std::string scopeName);
/// Destructor. destroyes all information of the scope
virtual ~IdentifierScope();
IdentifierScopeWeakPtr getParentScope() const;
IdentifierScopeWeakPtr getRootScope() const;
bool hasSubScope( std::string scopeName ) const;
IdentifierScopePtr getSubScope(std::string scopeName) const;
void addIdentifierDeclaration( std::string qualifiedName, ASTNodePtr declaration);
ASTNodePtr getIdentifierDeclaration( std::string qualifiedName ) const;
protected:
/*! protects direct creation. use static 'createScope/createSubScope'
*/
IdentifierScope(IdentifierScopeWeakPtr parent);
private:
void registerSubScope(std::string scopeName, IdentifierScopePtr& subScope );
void addLocalIdentifier( std::string localName, ASTNodePtr declaration);
ASTNodePtr getLocalIdentifier( std::string localName );
bool isLocalIdentifier( std::string localName );
typedef std::map<std::string, IdentifierScopePtr> SubScopeMap;
typedef std::map<std::string, ASTNodePtr> IdentifierDeclarationMap;
SubScopeMap subScopes_; //< sub scopes can be defined by types and namespaces
IdentifierDeclarationMap identifierDeclaration_; //< stores declaration of this scope !
IdentifierScopeWeakPtr parent_;
IdentifierScopeWeakPtr root_; // the file scope
};
// Inlines methods for IdentifierScope:
// ----------------------------------------------
inline IdentifierScopeWeakPtr
IdentifierScope::getParentScope() const
{
return parent_;
}
inline IdentifierScopeWeakPtr
IdentifierScope::getRootScope() const
{
return root_;
}
inline IdentifierScope::~IdentifierScope()
{
}
inline IdentifierScopePtr IdentifierScope::createScope(IdentifierScopeWeakPtr parent)
{
IdentifierScopePtr scope( new IdentifierScope(parent) );
if ( ! boost::make_shared(parent) )
scope->root_ = scope;
return scope;
}
inline IdentifierScopeException::IdentifierScopeException(ExceptionType type)
{
reason_ = type;
}
} // namespace Refactoring
#endif // RFTA_IDENTIFIERSCOPE_H
--- NEW FILE: IdentifierScope.cpp ---
// //////////////////////////////////////////////////////////////////////////
// (c)Copyright 2003, Andre Baresel.
// Created: 2003/05/13
// //////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "IdentifierScope.h"
namespace Refactoring
{
// constructor, sets parent and root node information
IdentifierScope::IdentifierScope(IdentifierScopeWeakPtr parent)
{
parent_ = parent;
IdentifierScopePtr tmp = boost::make_shared(parent_);
if ( tmp )
root_ = tmp->getRootScope();
}
IdentifierScopePtr
IdentifierScope::createSubScope(IdentifierScopeWeakPtr parent, std::string scopeName)
{
IdentifierScopePtr shrd_p = boost::make_shared(parent);
if ( shrd_p->hasSubScope( scopeName ) )
throw IdentifierScopeException(IdentifierScopeException::InvalidScope);
IdentifierScopePtr subScope = IdentifierScope::createScope(parent);
shrd_p->registerSubScope(scopeName, subScope);
return subScope;
}
bool
IdentifierScope::hasSubScope( std::string scopeName ) const
{
SubScopeMap::const_iterator it = subScopes_.find(scopeName);
return ( it != subScopes_.end() );
}
IdentifierScopePtr
IdentifierScope::getSubScope(std::string scopeName) const
{
SubScopeMap::const_iterator it = subScopes_.find(scopeName);
if ( it != subScopes_.end() )
return it->second;
else
return IdentifierScopePtr ();
}
void
IdentifierScope::registerSubScope(std::string scopeName, IdentifierScopePtr& subScope )
{
subScopes_[scopeName] = subScope;
}
void
IdentifierScope::addIdentifierDeclaration( std::string qualifiedName, ASTNodePtr declaration)
{
int pos = qualifiedName.find(':');
if ( pos != std::string::npos )
{
// check validity of the name:
if ( pos == qualifiedName.length()-1 ||
qualifiedName[pos+1] != ':' )
throw IdentifierScopeException(IdentifierScopeException::InvalidIdentifierName);
// check if qualified name references 'root-scope'
if ( pos == 0 )
boost::make_shared(root_)->addIdentifierDeclaration(qualifiedName.substr(2),declaration);
// find out sub scope:
std::string subScopeName = qualifiedName.substr(0,pos-1);
if (!hasSubScope( subScopeName ))
throw IdentifierScopeException(IdentifierScopeException::WrongQualifiedIdentifier);
// call registration routine of sub scope
getSubScope( subScopeName ) ->addIdentifierDeclaration(qualifiedName.substr(pos+2),declaration);
} else
{
// identifier of this scope.
IdentifierDeclarationMap::iterator it = identifierDeclaration_.find( qualifiedName );
if ( it != identifierDeclaration_.end() )
throw IdentifierScopeException(IdentifierScopeException::IdentifierDeclaredTwice);
identifierDeclaration_[qualifiedName] = declaration;
}
}
ASTNodePtr
IdentifierScope::getIdentifierDeclaration( std::string qualifiedName ) const
{
int pos = qualifiedName.find(':');
if ( pos != std::string::npos )
{
// check validity of the name:
if ( pos == qualifiedName.length()-1 ||
qualifiedName[pos+1] != ':' )
throw IdentifierScopeException(IdentifierScopeException::InvalidIdentifierName);
// check if qualified name references 'root-scope'
if ( pos == 0 )
return boost::make_shared(root_)->getIdentifierDeclaration(qualifiedName.substr(2));
// find out sub scope:
std::string subScopeName = qualifiedName.substr(0,pos);
if (!hasSubScope( subScopeName ))
throw IdentifierScopeException(IdentifierScopeException::WrongQualifiedIdentifier);
// call registration routine of sub scope
return getSubScope( subScopeName ) ->getIdentifierDeclaration(qualifiedName.substr(pos+2));
} else
{
// identifier of this scope.
IdentifierDeclarationMap::const_iterator it = identifierDeclaration_.find( qualifiedName );
if ( it == identifierDeclaration_.end() )
return ASTNodePtr ();
else
return it->second;
}
}
void
IdentifierScope::addLocalIdentifier( std::string localName, ASTNodePtr declaration)
{
}
ASTNodePtr
IdentifierScope::getLocalIdentifier( std::string localName )
{
return ASTNodePtr ();
}
bool IdentifierScope::isLocalIdentifier( std::string localName )
{
return false;
}
const char *
IdentifierScopeException::what() const
{
switch (reason_)
{
case InvalidScope:
return "The specified scope name is not valid.";
case InvalidIdentifierName:
return "The specified identifier name is not valid.";
case WrongQualifiedIdentifier:
return "The identifier qualified name could not be resolved.";
case IdentifierDeclaredTwice:
return "Tried to register identifier declaration twice.";
default:
return "Internal problem. Exception code has not been descriped. (see " __FILE__ " method 'IdentifierScopeException::what')";
}
}
} // namespace Refactoring
|