| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| #include <precomp.h> |
| #include "c_reposypart.hxx" |
| |
| |
| // NOT FULLY DECLARED SERVICES |
| #include <ary/getncast.hxx> |
| #include <ary/namesort.hxx> |
| #include <ary/cpp/c_builtintype.hxx> |
| #include <ary/cpp/c_class.hxx> |
| #include <ary/cpp/c_cppentity.hxx> |
| #include <ary/cpp/c_define.hxx> |
| #include <ary/cpp/c_enum.hxx> |
| #include <ary/cpp/c_enuval.hxx> |
| #include <ary/cpp/c_funct.hxx> |
| #include <ary/cpp/c_macro.hxx> |
| #include <ary/cpp/c_namesp.hxx> |
| #include <ary/cpp/c_tydef.hxx> |
| #include <ary/cpp/c_type.hxx> |
| #include <ary/cpp/usedtype.hxx> |
| #include <ary/cpp/c_vari.hxx> |
| #include <ary/loc/locp_le.hxx> |
| #include <ary/getncast.hxx> |
| #include <loc_internalgate.hxx> |
| #include <reposy.hxx> |
| #include "ca_ce.hxx" |
| #include "ca_def.hxx" |
| #include "ca_type.hxx" |
| #include "cs_ce.hxx" |
| #include "cs_def.hxx" |
| #include "cs_type.hxx" |
| |
| |
| |
| namespace |
| { |
| |
| using ::ary::GlobalId; |
| using ::ary::Rid; |
| using namespace ::ary::cpp; |
| |
| |
| inline bool |
| IsDefine( const GlobalId & i_id ) |
| { |
| return i_id.Class() == Define::class_id |
| OR |
| i_id.Class() == Macro::class_id; |
| } |
| |
| |
| /// Find Ces |
| class TypeConnector |
| { |
| public: |
| TypeConnector( |
| Gate & i_gate ) |
| : pGate(&i_gate) {} |
| ~TypeConnector() {} |
| |
| void operator()( |
| Type & io_rType ) const; |
| private: |
| // DATA |
| Gate * pGate; |
| }; |
| |
| /// Find Ces only known from base class name scope. |
| class TypeConnector2ndTry |
| { |
| public: |
| TypeConnector2ndTry( |
| Gate & i_gate ) |
| : pGate(&i_gate) {} |
| ~TypeConnector2ndTry() {} |
| |
| void operator()( |
| Type & io_rType ) const; |
| private: |
| // DATA |
| Gate * pGate; |
| }; |
| |
| /// Reconnect (in both directions) base-derived relations of classes. |
| class HierarchyLinker |
| { |
| public: |
| HierarchyLinker( |
| Gate & i_gate ) |
| : pGate(&i_gate) {} |
| |
| ~HierarchyLinker() {} |
| |
| void operator()( |
| Class & io_rCe ) const; |
| private: |
| // DATA |
| Gate * pGate; |
| }; |
| |
| |
| |
| /// Helper functor for ->RepositoryPartition::Get_AlphabeticalList(). |
| template <class TRAITS> |
| struct MakeGlobalId |
| { |
| GlobalId operator()( |
| typename TRAITS::id_type |
| i_id ) const |
| { |
| return GlobalId( TRAITS::EntityOf_(i_id).AryClass(), |
| i_id.Value() ); |
| } |
| }; |
| |
| |
| |
| |
| /** Compare two {->GlobalId}s. |
| |
| |
| @todo Move this up to the definition of GlobalId<>. |
| */ |
| struct LesserGlobal |
| { |
| LesserGlobal( |
| const Ce_Storage & i_ces, |
| const Def_Storage & i_des ) |
| : rCes(i_ces), rDes(i_des) {} |
| |
| bool operator()( |
| GlobalId i_1, |
| GlobalId i_2 ) const; |
| |
| private: |
| const String & NameOf( |
| GlobalId i_id ) const; |
| // DATA |
| const Ce_Storage & rCes; |
| const Def_Storage & rDes; |
| ::ary::LesserName aLess; |
| }; |
| |
| |
| bool |
| LesserGlobal::operator()( GlobalId i_1, |
| GlobalId i_2 ) const |
| { |
| String s1 = NameOf(i_1); |
| String s2 = NameOf(i_2); |
| |
| if (s1 != s2) |
| return aLess(s1, s2); |
| |
| if ( IsDefine(i_1) != IsDefine(i_2) ) |
| { |
| return NOT IsDefine(i_2); |
| } |
| else if (IsDefine(i_1)) |
| { |
| return i_1.Class() < i_2.Class(); |
| } |
| |
| return Ce_GlobalCompare::Lesser_( |
| rCes[i_1.Id()], |
| rCes[i_2.Id()] ); |
| } |
| |
| |
| } // namespace anonymous |
| |
| |
| |
| |
| |
| |
| namespace ary |
| { |
| namespace cpp |
| { |
| |
| DYN InternalGate & |
| InternalGate::Create_Partition_(RepositoryCenter & i_center) |
| { |
| return *new RepositoryPartition(i_center); |
| } |
| |
| |
| RepositoryPartition::RepositoryPartition(RepositoryCenter & i_center) |
| : pRepositoryCenter(&i_center), |
| pCes(0), |
| pTypes(0), |
| pDefs(0), |
| pLocations(& loc::InternalGate::Create_Locations_()) |
| { |
| pCes = new CeAdmin(*this); |
| pTypes = new TypeAdmin(*this); |
| pDefs = new DefAdmin(*this); |
| pCes->Set_Related(*pTypes); |
| } |
| |
| RepositoryPartition::~RepositoryPartition() |
| { |
| } |
| |
| void |
| RepositoryPartition::Calculate_AllSecondaryInformation() |
| // const ::autodoc::Options & ) |
| { |
| // KORR_FUTURE |
| // Forward the options from here. |
| |
| Connect_AllTypes_2_TheirRelated_CodeEntites(); |
| } |
| |
| const String & |
| RepositoryPartition::RepositoryTitle() const |
| { |
| return static_cast< ary::Repository* >(pRepositoryCenter)->Title(); |
| } |
| |
| const CodeEntity * |
| RepositoryPartition::Search_RelatedCe(Type_id i_type) const |
| { |
| if (NOT i_type.IsValid()) |
| return 0; |
| |
| Ce_id |
| ce_id = pTypes->Find_Type(i_type).RelatedCe(); |
| return ce_id.IsValid() |
| ? & pCes->Find_Ce(ce_id) |
| : (CodeEntity*)(0); |
| } |
| |
| const ::ary::cpp::CppEntity * |
| RepositoryPartition::Search_Entity(GlobalId i_id) const |
| { |
| if (i_id.Id() == 0) |
| return 0; |
| |
| if ( NOT IsDefine(i_id) ) |
| { |
| // Shall make sure this is a C++ CodeEntity: |
| csv_assert( i_id.Class() >= Namespace::class_id |
| AND |
| i_id.Class() < BuiltInType::class_id |
| && "Unexpected entity type in cpp::RepositoryPartition" |
| "::Search_Entity()." ); |
| return & Ces().Find_Ce( Ce_id(i_id.Id()) ); |
| } |
| else |
| { |
| return & Defs().Find_Def( De_id(i_id.Id()) ); |
| } |
| } |
| |
| |
| const CePilot & |
| RepositoryPartition::Ces() const |
| { |
| csv_assert(pCes != 0); |
| return *pCes; |
| } |
| |
| const DefPilot & |
| RepositoryPartition::Defs() const |
| { |
| csv_assert(pDefs != 0); |
| return *pDefs; |
| } |
| |
| const TypePilot & |
| RepositoryPartition::Types() const |
| { |
| csv_assert(pTypes != 0); |
| return *pTypes; |
| } |
| |
| const loc::LocationPilot & |
| RepositoryPartition::Locations() const |
| { |
| csv_assert(pLocations != 0); |
| return *pLocations; |
| } |
| |
| CePilot & |
| RepositoryPartition::Ces() |
| { |
| csv_assert(pCes != 0); |
| return *pCes; |
| } |
| |
| DefPilot & |
| RepositoryPartition::Defs() |
| { |
| csv_assert(pDefs != 0); |
| return *pDefs; |
| } |
| |
| TypePilot & |
| RepositoryPartition::Types() |
| { |
| csv_assert(pTypes != 0); |
| return *pTypes; |
| } |
| |
| loc::LocationPilot & |
| RepositoryPartition::Locations() |
| { |
| csv_assert(pLocations != 0); |
| return *pLocations; |
| } |
| |
| |
| void |
| RepositoryPartition::Connect_AllTypes_2_TheirRelated_CodeEntites() |
| { |
| TypeConnector |
| aConnector(*this); |
| std::for_each( pTypes->Storage().BeginUnreserved(), |
| pTypes->Storage().End(), |
| aConnector ); |
| |
| typedef ::ary::stg::filter_iterator<CodeEntity,Class> |
| filter_class_iter; |
| |
| HierarchyLinker |
| aHierarchyLinker(*this); |
| filter_class_iter itEnd( pCes->Storage().End() ); |
| for ( filter_class_iter it( pCes->Storage().BeginUnreserved() ); |
| it != itEnd; |
| ++it ) |
| { |
| if (NOT it.IsValid()) |
| continue; |
| |
| if (is_type<Class>(*it)) |
| aHierarchyLinker(ary_cast<Class>(*it)); |
| } |
| |
| TypeConnector2ndTry |
| aConnector2ndTry(*this); |
| std::for_each( pTypes->Storage().BeginUnreserved(), |
| pTypes->Storage().End(), |
| aConnector2ndTry ); |
| } |
| |
| template <class COMPARE> |
| void Add2Result( |
| List_GlobalIds & o_result, |
| const SortedIds<COMPARE> & |
| i_data, |
| const char * i_begin, |
| const char * i_end ); |
| template <class COMPARE> |
| void |
| Add2Result( List_GlobalIds & o_result, |
| const SortedIds<COMPARE> & i_data, |
| const char * i_begin, |
| const char * i_end ) |
| { |
| const size_t |
| previous_size = o_result.size(); |
| typename std::vector<typename COMPARE::id_type>::const_iterator |
| it_beg = i_data.LowerBound(i_begin); |
| typename std::vector<typename COMPARE::id_type>::const_iterator |
| it_end = i_data.LowerBound(i_end); |
| size_t |
| count_added = static_cast<size_t>( std::distance(it_beg,it_end) ); |
| o_result.insert( o_result.end(), |
| count_added, |
| GlobalId() ); |
| List_GlobalIds::iterator |
| it_out = o_result.begin() + previous_size; |
| std::transform( it_beg, it_end, |
| it_out, |
| MakeGlobalId<COMPARE>() ); |
| } |
| |
| |
| uintt |
| RepositoryPartition::Get_AlphabeticalList( List_GlobalIds & o_result, |
| const char * i_begin, |
| const char * i_end ) const |
| { |
| size_t |
| ret = o_result.size(); |
| |
| const Ce_Storage & |
| ce_storage = pCes->Storage(); |
| const Def_Storage & |
| def_storage = pDefs->Storage(); |
| |
| Add2Result( o_result, |
| ce_storage.TypeIndex(), |
| i_begin, i_end ); |
| Add2Result( o_result, |
| ce_storage.OperationIndex(), |
| i_begin, i_end ); |
| Add2Result( o_result, |
| ce_storage.DataIndex(), |
| i_begin, i_end ); |
| Add2Result( o_result, |
| def_storage.DefineIndex(), |
| i_begin, i_end ); |
| Add2Result( o_result, |
| def_storage.MacroIndex(), |
| i_begin, i_end ); |
| |
| LesserGlobal |
| aLess(ce_storage, def_storage); |
| |
| std::sort(o_result.begin(), o_result.end(), aLess); |
| |
| return o_result.size() - ret; |
| } |
| |
| |
| |
| |
| } // namespace cpp |
| } // namespace ary |
| |
| |
| |
| |
| |
| namespace |
| { |
| |
| |
| void |
| TypeConnector::operator()( Type & io_rType ) const |
| { |
| csv_assert(pGate != 0); |
| UsedType * |
| pt = ::ary::ary_cast<UsedType>(&io_rType); |
| if (pt != 0) |
| pt->Connect2Ce(pGate->Ces()); |
| } |
| |
| void |
| TypeConnector2ndTry::operator()( Type & io_rType ) const |
| { |
| csv_assert(pGate != 0); |
| UsedType * |
| pt = ::ary::ary_cast<UsedType>(&io_rType); |
| if (pt != 0) |
| pt->Connect2CeOnlyKnownViaBaseClass(*pGate); |
| } |
| |
| void |
| HierarchyLinker::operator()( Class & io_rCe ) const |
| { |
| csv_assert( ::ary::is_type<Class>(io_rCe) ); |
| Class & |
| rClass = io_rCe; |
| |
| for ( List_Bases::const_iterator it = rClass.BaseClasses().begin(); |
| it != rClass.BaseClasses().end(); |
| ++it ) |
| { |
| const CodeEntity * |
| pCe = 0; |
| Type_id |
| nTid = (*it).nId; |
| for ( pCe = pGate->Search_RelatedCe(nTid); |
| ary::ary_cast<Typedef>(pCe) != 0; |
| pCe = pGate->Search_RelatedCe(nTid) ) |
| { |
| nTid = static_cast< const Typedef* >(pCe)->DescribingType(); |
| } |
| const Class * |
| pClass = ary::ary_cast<Class>(pCe); |
| if (pClass == 0) |
| return; |
| // KORR_FUTURE: we need a non const Find_Class() |
| const_cast< Class* >(pClass)->Add_KnownDerivative( io_rCe.CeId() ); |
| } |
| } |
| |
| const String & |
| LesserGlobal::NameOf(GlobalId i_id) const |
| { |
| if ( NOT IsDefine(i_id) ) |
| { |
| return rCes[i_id.Id()].LocalName(); |
| } |
| else |
| { |
| return rDes[i_id.Id()].LocalName(); |
| } |
| } |
| |
| |
| |
| } // namespace anonymous |