/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /************************************************************************* * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * Copyright 2000, 2010 Oracle and/or its affiliates. * * OpenOffice.org - a multi-platform office productivity suite * * This file is part of OpenOffice.org. * * OpenOffice.org is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 3 * only, as published by the Free Software Foundation. * * OpenOffice.org is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License version 3 for more details * (a copy is included in the LICENSE file that accompanied this code). * * You should have received a copy of the GNU Lesser General Public License * version 3 along with OpenOffice.org. If not, see * * for a copy of the LGPLv3 License. * ************************************************************************/ #include #include "c_reposypart.hxx" // NOT FULLY DECLARED SERVICES #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #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 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 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(*it)) aHierarchyLinker(ary_cast(*it)); } TypeConnector2ndTry aConnector2ndTry(*this); std::for_each( pTypes->Storage().BeginUnreserved(), pTypes->Storage().End(), aConnector2ndTry ); } template void Add2Result( List_GlobalIds & o_result, const SortedIds & i_data, const char * i_begin, const char * i_end ); template void Add2Result( List_GlobalIds & o_result, const SortedIds & i_data, const char * i_begin, const char * i_end ) { const size_t previous_size = o_result.size(); typename std::vector::const_iterator it_beg = i_data.LowerBound(i_begin); typename std::vector::const_iterator it_end = i_data.LowerBound(i_end); size_t count_added = static_cast( 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() ); } 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(&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(&io_rType); if (pt != 0) pt->Connect2CeOnlyKnownViaBaseClass(*pGate); } void HierarchyLinker::operator()( Class & io_rCe ) const { csv_assert( ::ary::is_type(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(pCe) != 0; pCe = pGate->Search_RelatedCe(nTid) ) { nTid = static_cast< const Typedef* >(pCe)->DescribingType(); } const Class * pClass = ary::ary_cast(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 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */