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 |