1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 #include <precomp.h> 29 #include "c_reposypart.hxx" 30 31 32 // NOT FULLY DECLARED SERVICES 33 #include <ary/getncast.hxx> 34 #include <ary/namesort.hxx> 35 #include <ary/cpp/c_builtintype.hxx> 36 #include <ary/cpp/c_class.hxx> 37 #include <ary/cpp/c_cppentity.hxx> 38 #include <ary/cpp/c_define.hxx> 39 #include <ary/cpp/c_enum.hxx> 40 #include <ary/cpp/c_enuval.hxx> 41 #include <ary/cpp/c_funct.hxx> 42 #include <ary/cpp/c_macro.hxx> 43 #include <ary/cpp/c_namesp.hxx> 44 #include <ary/cpp/c_tydef.hxx> 45 #include <ary/cpp/c_type.hxx> 46 #include <ary/cpp/usedtype.hxx> 47 #include <ary/cpp/c_vari.hxx> 48 #include <ary/loc/locp_le.hxx> 49 #include <ary/getncast.hxx> 50 #include <loc_internalgate.hxx> 51 #include <reposy.hxx> 52 #include "ca_ce.hxx" 53 #include "ca_def.hxx" 54 #include "ca_type.hxx" 55 #include "cs_ce.hxx" 56 #include "cs_def.hxx" 57 #include "cs_type.hxx" 58 59 60 61 namespace 62 { 63 64 using ::ary::GlobalId; 65 using ::ary::Rid; 66 using namespace ::ary::cpp; 67 68 69 inline bool 70 IsDefine( const GlobalId & i_id ) 71 { 72 return i_id.Class() == Define::class_id 73 OR 74 i_id.Class() == Macro::class_id; 75 } 76 77 78 /// Find Ces 79 class TypeConnector 80 { 81 public: 82 TypeConnector( 83 Gate & i_gate ) 84 : pGate(&i_gate) {} 85 ~TypeConnector() {} 86 87 void operator()( 88 Type & io_rType ) const; 89 private: 90 // DATA 91 Gate * pGate; 92 }; 93 94 /// Find Ces only known from base class name scope. 95 class TypeConnector2ndTry 96 { 97 public: 98 TypeConnector2ndTry( 99 Gate & i_gate ) 100 : pGate(&i_gate) {} 101 ~TypeConnector2ndTry() {} 102 103 void operator()( 104 Type & io_rType ) const; 105 private: 106 // DATA 107 Gate * pGate; 108 }; 109 110 /// Reconnect (in both directions) base-derived relations of classes. 111 class HierarchyLinker 112 { 113 public: 114 HierarchyLinker( 115 Gate & i_gate ) 116 : pGate(&i_gate) {} 117 118 ~HierarchyLinker() {} 119 120 void operator()( 121 Class & io_rCe ) const; 122 private: 123 // DATA 124 Gate * pGate; 125 }; 126 127 128 129 /// Helper functor for ->RepositoryPartition::Get_AlphabeticalList(). 130 template <class TRAITS> 131 struct MakeGlobalId 132 { 133 GlobalId operator()( 134 typename TRAITS::id_type 135 i_id ) const 136 { 137 return GlobalId( TRAITS::EntityOf_(i_id).AryClass(), 138 i_id.Value() ); 139 } 140 }; 141 142 143 144 145 /** Compare two {->GlobalId}s. 146 147 148 @todo Move this up to the definition of GlobalId<>. 149 */ 150 struct LesserGlobal 151 { 152 LesserGlobal( 153 const Ce_Storage & i_ces, 154 const Def_Storage & i_des ) 155 : rCes(i_ces), rDes(i_des) {} 156 157 bool operator()( 158 GlobalId i_1, 159 GlobalId i_2 ) const; 160 161 private: 162 const String & NameOf( 163 GlobalId i_id ) const; 164 // DATA 165 const Ce_Storage & rCes; 166 const Def_Storage & rDes; 167 ::ary::LesserName aLess; 168 }; 169 170 171 bool 172 LesserGlobal::operator()( GlobalId i_1, 173 GlobalId i_2 ) const 174 { 175 String s1 = NameOf(i_1); 176 String s2 = NameOf(i_2); 177 178 if (s1 != s2) 179 return aLess(s1, s2); 180 181 if ( IsDefine(i_1) != IsDefine(i_2) ) 182 { 183 return NOT IsDefine(i_2); 184 } 185 else if (IsDefine(i_1)) 186 { 187 return i_1.Class() < i_2.Class(); 188 } 189 190 return Ce_GlobalCompare::Lesser_( 191 rCes[i_1.Id()], 192 rCes[i_2.Id()] ); 193 } 194 195 196 } // namespace anonymous 197 198 199 200 201 202 203 namespace ary 204 { 205 namespace cpp 206 { 207 208 DYN InternalGate & 209 InternalGate::Create_Partition_(RepositoryCenter & i_center) 210 { 211 return *new RepositoryPartition(i_center); 212 } 213 214 215 RepositoryPartition::RepositoryPartition(RepositoryCenter & i_center) 216 : pRepositoryCenter(&i_center), 217 pCes(0), 218 pTypes(0), 219 pDefs(0), 220 pLocations(& loc::InternalGate::Create_Locations_()) 221 { 222 pCes = new CeAdmin(*this); 223 pTypes = new TypeAdmin(*this); 224 pDefs = new DefAdmin(*this); 225 pCes->Set_Related(*pTypes); 226 } 227 228 RepositoryPartition::~RepositoryPartition() 229 { 230 } 231 232 void 233 RepositoryPartition::Calculate_AllSecondaryInformation() 234 // const ::autodoc::Options & ) 235 { 236 // KORR_FUTURE 237 // Forward the options from here. 238 239 Connect_AllTypes_2_TheirRelated_CodeEntites(); 240 } 241 242 const String & 243 RepositoryPartition::RepositoryTitle() const 244 { 245 return static_cast< ary::Repository* >(pRepositoryCenter)->Title(); 246 } 247 248 const CodeEntity * 249 RepositoryPartition::Search_RelatedCe(Type_id i_type) const 250 { 251 if (NOT i_type.IsValid()) 252 return 0; 253 254 Ce_id 255 ce_id = pTypes->Find_Type(i_type).RelatedCe(); 256 return ce_id.IsValid() 257 ? & pCes->Find_Ce(ce_id) 258 : (CodeEntity*)(0); 259 } 260 261 const ::ary::cpp::CppEntity * 262 RepositoryPartition::Search_Entity(GlobalId i_id) const 263 { 264 if (i_id.Id() == 0) 265 return 0; 266 267 if ( NOT IsDefine(i_id) ) 268 { 269 // Shall make sure this is a C++ CodeEntity: 270 csv_assert( i_id.Class() >= Namespace::class_id 271 AND 272 i_id.Class() < BuiltInType::class_id 273 && "Unexpected entity type in cpp::RepositoryPartition" 274 "::Search_Entity()." ); 275 return & Ces().Find_Ce( Ce_id(i_id.Id()) ); 276 } 277 else 278 { 279 return & Defs().Find_Def( De_id(i_id.Id()) ); 280 } 281 } 282 283 284 const CePilot & 285 RepositoryPartition::Ces() const 286 { 287 csv_assert(pCes != 0); 288 return *pCes; 289 } 290 291 const DefPilot & 292 RepositoryPartition::Defs() const 293 { 294 csv_assert(pDefs != 0); 295 return *pDefs; 296 } 297 298 const TypePilot & 299 RepositoryPartition::Types() const 300 { 301 csv_assert(pTypes != 0); 302 return *pTypes; 303 } 304 305 const loc::LocationPilot & 306 RepositoryPartition::Locations() const 307 { 308 csv_assert(pLocations != 0); 309 return *pLocations; 310 } 311 312 CePilot & 313 RepositoryPartition::Ces() 314 { 315 csv_assert(pCes != 0); 316 return *pCes; 317 } 318 319 DefPilot & 320 RepositoryPartition::Defs() 321 { 322 csv_assert(pDefs != 0); 323 return *pDefs; 324 } 325 326 TypePilot & 327 RepositoryPartition::Types() 328 { 329 csv_assert(pTypes != 0); 330 return *pTypes; 331 } 332 333 loc::LocationPilot & 334 RepositoryPartition::Locations() 335 { 336 csv_assert(pLocations != 0); 337 return *pLocations; 338 } 339 340 341 void 342 RepositoryPartition::Connect_AllTypes_2_TheirRelated_CodeEntites() 343 { 344 TypeConnector 345 aConnector(*this); 346 std::for_each( pTypes->Storage().BeginUnreserved(), 347 pTypes->Storage().End(), 348 aConnector ); 349 350 typedef ::ary::stg::filter_iterator<CodeEntity,Class> 351 filter_class_iter; 352 353 HierarchyLinker 354 aHierarchyLinker(*this); 355 filter_class_iter itEnd( pCes->Storage().End() ); 356 for ( filter_class_iter it( pCes->Storage().BeginUnreserved() ); 357 it != itEnd; 358 ++it ) 359 { 360 if (NOT it.IsValid()) 361 continue; 362 363 if (is_type<Class>(*it)) 364 aHierarchyLinker(ary_cast<Class>(*it)); 365 } 366 367 TypeConnector2ndTry 368 aConnector2ndTry(*this); 369 std::for_each( pTypes->Storage().BeginUnreserved(), 370 pTypes->Storage().End(), 371 aConnector2ndTry ); 372 } 373 374 template <class COMPARE> 375 void Add2Result( 376 List_GlobalIds & o_result, 377 const SortedIds<COMPARE> & 378 i_data, 379 const char * i_begin, 380 const char * i_end ); 381 template <class COMPARE> 382 void 383 Add2Result( List_GlobalIds & o_result, 384 const SortedIds<COMPARE> & i_data, 385 const char * i_begin, 386 const char * i_end ) 387 { 388 const size_t 389 previous_size = o_result.size(); 390 typename std::vector<typename COMPARE::id_type>::const_iterator 391 it_beg = i_data.LowerBound(i_begin); 392 typename std::vector<typename COMPARE::id_type>::const_iterator 393 it_end = i_data.LowerBound(i_end); 394 size_t 395 count_added = static_cast<size_t>( std::distance(it_beg,it_end) ); 396 o_result.insert( o_result.end(), 397 count_added, 398 GlobalId() ); 399 List_GlobalIds::iterator 400 it_out = o_result.begin() + previous_size; 401 std::transform( it_beg, it_end, 402 it_out, 403 MakeGlobalId<COMPARE>() ); 404 } 405 406 407 uintt 408 RepositoryPartition::Get_AlphabeticalList( List_GlobalIds & o_result, 409 const char * i_begin, 410 const char * i_end ) const 411 { 412 size_t 413 ret = o_result.size(); 414 415 const Ce_Storage & 416 ce_storage = pCes->Storage(); 417 const Def_Storage & 418 def_storage = pDefs->Storage(); 419 420 Add2Result( o_result, 421 ce_storage.TypeIndex(), 422 i_begin, i_end ); 423 Add2Result( o_result, 424 ce_storage.OperationIndex(), 425 i_begin, i_end ); 426 Add2Result( o_result, 427 ce_storage.DataIndex(), 428 i_begin, i_end ); 429 Add2Result( o_result, 430 def_storage.DefineIndex(), 431 i_begin, i_end ); 432 Add2Result( o_result, 433 def_storage.MacroIndex(), 434 i_begin, i_end ); 435 436 LesserGlobal 437 aLess(ce_storage, def_storage); 438 439 std::sort(o_result.begin(), o_result.end(), aLess); 440 441 return o_result.size() - ret; 442 } 443 444 445 446 447 } // namespace cpp 448 } // namespace ary 449 450 451 452 453 454 namespace 455 { 456 457 458 void 459 TypeConnector::operator()( Type & io_rType ) const 460 { 461 csv_assert(pGate != 0); 462 UsedType * 463 pt = ::ary::ary_cast<UsedType>(&io_rType); 464 if (pt != 0) 465 pt->Connect2Ce(pGate->Ces()); 466 } 467 468 void 469 TypeConnector2ndTry::operator()( Type & io_rType ) const 470 { 471 csv_assert(pGate != 0); 472 UsedType * 473 pt = ::ary::ary_cast<UsedType>(&io_rType); 474 if (pt != 0) 475 pt->Connect2CeOnlyKnownViaBaseClass(*pGate); 476 } 477 478 void 479 HierarchyLinker::operator()( Class & io_rCe ) const 480 { 481 csv_assert( ::ary::is_type<Class>(io_rCe) ); 482 Class & 483 rClass = io_rCe; 484 485 for ( List_Bases::const_iterator it = rClass.BaseClasses().begin(); 486 it != rClass.BaseClasses().end(); 487 ++it ) 488 { 489 const CodeEntity * 490 pCe = 0; 491 Type_id 492 nTid = (*it).nId; 493 for ( pCe = pGate->Search_RelatedCe(nTid); 494 ary::ary_cast<Typedef>(pCe) != 0; 495 pCe = pGate->Search_RelatedCe(nTid) ) 496 { 497 nTid = static_cast< const Typedef* >(pCe)->DescribingType(); 498 } 499 const Class * 500 pClass = ary::ary_cast<Class>(pCe); 501 if (pClass == 0) 502 return; 503 // KORR_FUTURE: we need a non const Find_Class() 504 const_cast< Class* >(pClass)->Add_KnownDerivative( io_rCe.CeId() ); 505 } 506 } 507 508 const String & 509 LesserGlobal::NameOf(GlobalId i_id) const 510 { 511 if ( NOT IsDefine(i_id) ) 512 { 513 return rCes[i_id.Id()].LocalName(); 514 } 515 else 516 { 517 return rDes[i_id.Id()].LocalName(); 518 } 519 } 520 521 522 523 } // namespace anonymous 524