1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include "i2s_calculator.hxx"
23 // NOT FULLY DEFINED SERVICES
26 #include <cosv/file.hxx>
27 #include <ary/qualiname.hxx>
28 #include <ary/idl/i_enum.hxx>
29 #include <ary/idl/i_exception.hxx>
30 #include <ary/idl/i_function.hxx>
31 #include <ary/idl/i_gate.hxx>
32 #include <ary/idl/i_interface.hxx>
33 #include <ary/idl/ik_interface.hxx>
34 #include <ary/idl/i_module.hxx>
35 #include <ary/idl/i_property.hxx>
36 #include <ary/idl/i_service.hxx>
37 #include <ary/idl/i_singleton.hxx>
38 #include <ary/idl/i_siservice.hxx>
39 #include <ary/idl/i_sisingleton.hxx>
40 #include <ary/idl/i_struct.hxx>
41 #include <ary/idl/i_structelem.hxx>
42 #include <ary/idl/i_typedef.hxx>
43 #include <ary/idl/ip_ce.hxx>
44 #include <ary/idl/ip_type.hxx>
45 #include <ary/namesort.hxx>
46 #include <nametreenode.hxx>
47 #include "i_nnfinder.hxx"
49 #include "ia_type.hxx"
51 #include "is_type.hxx"
53 #include "it_explicit.hxx"
54 #include "it_sequence.hxx"
55 #include "it_xnameroom.hxx"
65 SecondariesCalculator::SearchCe4Type(Type_id i_type
)
68 ce
= lhf_Search_CeFromTypeId(i_type
);
70 return ary_cast
<DEST
>(& my_CeStorage()[ce
]);
75 typedef stg::const_iterator
<CodeEntity
> stg_citerator
;
76 typedef stg::iterator
<CodeEntity
> stg_iterator
;
78 typedef stg::filter_iterator
<CodeEntity
,Interface
>
81 typedef stg::filter_iterator
<Type
,ExplicitType
>
82 explicittype_iterator
;
84 typedef ary::stg::const_filter_iterator
<CodeEntity
,Typedef
>
89 SecondariesCalculator::lhf_SearchService( Type_id i_nType
)
91 return SearchCe4Type
<Service
>(i_nType
);
95 SecondariesCalculator::lhf_SearchInterface( Type_id i_nType
)
97 return SearchCe4Type
<Interface
>(i_nType
);
101 SecondariesCalculator::lhf_SearchStruct( Type_id i_nType
)
103 return SearchCe4Type
<Struct
>(i_nType
);
107 SecondariesCalculator::lhf_SearchException( Type_id i_nType
)
109 return SearchCe4Type
<Exception
>(i_nType
);
112 inline const Ce_Storage
&
113 SecondariesCalculator::my_CeStorage() const
115 csv_assert(pCes
!= 0);
116 return pCes
->Storage();
119 inline const Type_Storage
&
120 SecondariesCalculator::my_TypeStorage() const
122 csv_assert(pTypes
!= 0);
123 return pTypes
->Storage();
127 SecondariesCalculator::my_CeStorage()
129 csv_assert(pCes
!= 0);
130 return pCes
->Storage();
133 inline Type_Storage
&
134 SecondariesCalculator::my_TypeStorage()
136 csv_assert(pTypes
!= 0);
137 return pTypes
->Storage();
141 SecondariesCalculator::insert_into2sList( CodeEntity
& o_out
,
144 { o_out
.Secondaries().Access_List(i_listIndex
).push_back(i_nCe
); }
147 SecondariesCalculator::SecondariesCalculator( CeAdmin
& i_ces
,
148 TypeAdmin
& i_types
)
154 SecondariesCalculator::~SecondariesCalculator()
160 SecondariesCalculator::CheckAllInterfaceBases()
163 rGlobalNamespace
= pCes
->GlobalNamespace();
165 aXInterface("::com::sun::star::uno::XInterface","::");
168 rType
= pTypes
->CheckIn_Type( aXInterface
,
170 rGlobalNamespace
.CeId(),
173 nTypeXInterface
= rType
.TypeId();
175 rExplType
= ary_cast
<ExplicitType
>(rType
);
177 nCeXInterface
= lhf_Search_CeForType(rExplType
);
179 interface_iterator
itEnd( my_CeStorage().End() );
180 for ( interface_iterator
it( my_CeStorage().BeginUnreserved() );
184 if (NOT it
.IsValid())
189 if ( NOT rInterface
.HasBase() // According to UNO IDL syntax, an interface without base has com::sun::star::uno::XInterface as base.
190 AND rInterface
.CeId() != nCeXInterface
) // XInterface must not be base of itself.
192 rInterface
.Add_Base(nTypeXInterface
, 0);
198 SecondariesCalculator::Connect_Types2Ces()
200 explicittype_iterator
itEnd( my_TypeStorage().End() );
201 for ( explicittype_iterator
it( my_TypeStorage().BeginUnreserved() );
205 if (NOT it
.IsValid())
209 rType
= ary_cast
<ExplicitType
>(*it
);
211 nRelatedCe
= lhf_Search_CeForType(rType
);
212 if (nRelatedCe
.IsValid())
215 pNew
= new Ce_Type(nRelatedCe
, rType
.TemplateParameters());
216 my_TypeStorage().Replace_Entity( rType
.TypeId(),
223 SecondariesCalculator::Gather_CrossReferences()
227 for ( stg_iterator it
= my_CeStorage().Begin();
228 it
!= my_CeStorage().End();
231 (*it
).Accept( static_cast< SPInst_asHost
& >(*this) );
239 SecondariesCalculator::Make_Links2DeveloperManual(
240 const String
& i_devman_reffilepath
)
243 aFile(i_devman_reffilepath
, csv::CFM_READ
);
248 Read_Links2DevManual(aFile
);
261 struct OrderCeIdsByName
264 const Ce_Storage
& i_storage
)
265 : rStorage(i_storage
),
271 return aNameComparison( rStorage
[i_ce1
].LocalName(),
272 rStorage
[i_ce2
].LocalName() );
276 const Ce_Storage
& rStorage
;
277 LesserName aNameComparison
;
286 SecondariesCalculator::do_Process( const Service
& i_rData
)
289 rService
= ary_cast
<Service
>(i_rData
);
292 assignImplementation_toAServicesInterfaces( rService
.CeId(),
294 interface_2s_ExportingServices
);
295 // Services and their interfaces:
296 recursive_AssignIncludingService(rService
.CeId(), rService
);
300 SecondariesCalculator::do_Process( const Interface
& i_rData
)
302 assign_AsDerivedInterface( ary_cast
<Interface
>(i_rData
) );
306 SecondariesCalculator::do_Process( const Struct
& i_rData
)
308 assign_AsDerivedStruct( ary_cast
<Struct
>(i_rData
) );
312 SecondariesCalculator::do_Process( const Exception
& i_rData
)
314 assign_AsDerivedException( ary_cast
<Exception
>(i_rData
) );
318 SecondariesCalculator::do_Process( const Typedef
& )
321 // Find out what was meant here ???
324 // rTypedef = ary_cast<Typedef>(i_rData);
328 SecondariesCalculator::do_Process( const Singleton
& i_rData
)
331 rSingleton
= ary_cast
<Singleton
>(i_rData
);
334 pServ
= lhf_SearchService(rSingleton
.AssociatedService());
337 insert_into2sUnique( *pServ
,
338 service_2s_InstantiatingSingletons
,
343 assignImplementation_toAServicesInterfaces( rSingleton
.CeId(),
344 lhf_Search_CeFromTypeId(rSingleton
.AssociatedService()),
345 interface_2s_ExportingSingletons
);
349 SecondariesCalculator::do_Process( const SglIfcService
& i_rData
)
351 const SglIfcService
&
352 rSglIfcService
= ary_cast
<SglIfcService
>(i_rData
);
354 assignImplementation_toAServicesInterfaces( rSglIfcService
.CeId(),
355 rSglIfcService
.CeId(),
356 interface_2s_ExportingServices
);
360 SecondariesCalculator::do_Process( const SglIfcSingleton
& i_rData
)
362 const SglIfcSingleton
&
363 rSglIfcSingleton
= ary_cast
<SglIfcSingleton
>(i_rData
);
365 Type_id nBase
= rSglIfcSingleton
.BaseInterface();
366 recursive_AssignImplementation_toExportedInterface( rSglIfcSingleton
.CeId(),
368 interface_2s_ExportingSingletons
);
372 SecondariesCalculator::do_Process( const Function
& i_rData
)
375 rFunction
= ary_cast
<Function
>(i_rData
);
377 recursive_AssignFunction_toCeAsReturn(rFunction
.CeId(), rFunction
.ReturnType());
379 for ( Function::ParamList::const_iterator itp
= rFunction
.Parameters().begin();
380 itp
!= rFunction
.Parameters().end();
383 recursive_AssignFunction_toCeAsParameter(rFunction
.CeId(), (*itp
).Type());
386 for ( Function::ExceptionList::const_iterator itx
= rFunction
.Exceptions().begin();
387 itx
!= rFunction
.Exceptions().end();
391 pX
= lhf_SearchException(*itx
);
394 insert_into2sUnique(*pX
, exception_2s_RaisingFunctions
, rFunction
.CeId());
400 SecondariesCalculator::do_Process( const StructElement
& i_rData
)
402 const StructElement
&
403 rStructElement
= ary_cast
<StructElement
>(i_rData
);
405 recursive_AssignStructElement_toCeAsDataType(rStructElement
.CeId(), rStructElement
.Type());
409 SecondariesCalculator::do_Process( const Property
& i_rData
)
412 rProperty
= ary_cast
<Property
>(i_rData
);
414 recursive_AssignStructElement_toCeAsDataType(rProperty
.CeId(), rProperty
.Type());
418 SecondariesCalculator::lhf_Search_CeForType( const ExplicitType
& i_rType
) const
420 const ExplicitNameRoom
&
421 rExplicitNameRoom
= ary_cast
<ExplicitNameRoom
>(
422 my_TypeStorage()[i_rType
.NameRoom()] );
424 rNodeFinder( my_CeStorage(),
425 rExplicitNameRoom
.NameChain_Begin(),
426 rExplicitNameRoom
.NameChain_End(),
429 if ( rExplicitNameRoom
.IsAbsolute() )
432 rGlobalNamespace
= ary_cast
<Module
>(
433 my_CeStorage()[predefined::ce_GlobalNamespace
]);
434 return Search_SubTree( rGlobalNamespace
,
440 rStartModule
= ary_cast
<Module
>(
441 my_CeStorage()[i_rType
.ModuleOfOccurrence()]);
442 Ce_id ret
= Search_SubTree_UpTillRoot( rStartModule
,
445 } // endif (rExplicitNameRoom.IsAbsolute()) else
449 SecondariesCalculator::lhf_Search_CeFromTypeId( Type_id i_nType
) const
451 if (NOT i_nType
.IsValid())
454 pType
= ary_cast
<Ce_Type
>( & my_TypeStorage()[i_nType
] );
461 SecondariesCalculator::assign_CurLink( char * i_text
,
462 const String
& i_link
,
463 const String
& i_linkUI
,
467 csv_assert(i_text
!= 0);
469 const ary::idl::Module
*
470 pModule
= & ary_cast
<Module
>(
471 my_CeStorage()[predefined::ce_GlobalNamespace
]);
473 char * pPastNext
= 0;
474 char * pNext
= i_text
;
476 (pPastNext
= strstr(pNext
,".")) != 0;
477 pNext
= pPastNext
+ 1 )
479 String
sNext(pNext
, pPastNext
-pNext
);
480 Ce_id nModule
= pModule
->Search_Name(sNext
);
481 if (nModule
.IsValid())
483 pModule
= ary_cast
<Module
>( & my_CeStorage()[nModule
] );
492 Cerr() << "Warning: Invalid line nr. "
494 << " in DevelopersGuide reference file:\n"
495 << reinterpret_cast< const char* >(i_text
)
502 pPastNext
= strchr(pNext
,':');
503 bool bMember
= pPastNext
!= 0;
504 String
sCe( pNext
, (bMember
? csv::str::size(pPastNext
-pNext
) : csv::str::maxsize
) );
507 // String sMember(bMember ? pPastNext+1, "");
509 Ce_id nCe
= pModule
->Search_Name(sCe
);
510 if (NOT nCe
.IsValid())
512 Cerr() << "Warning: Invalid line nr. "
514 << " in DevelopersGuide reference file:\n"
515 << reinterpret_cast< const char* >(i_text
)
522 rCe
= my_CeStorage()[nCe
];
526 rCe
.Secondaries().Add_Link2DescriptionInManual(i_link
, i_linkUI
);
528 rCe
.Secondaries().Add_Link2RefInManual(i_link
, i_linkUI
);
534 // Provisorial just doing nothing (or may be
535 // adding a link at main Ces lists).
537 // rCe.Secondaries().Add_Link2DescriptionInManual(i_link);
539 // rCe.Secondaries().Add_Link2RefInManual(i_link);
544 SecondariesCalculator::gather_Synonyms()
547 cstrg
= my_CeStorage();
548 typedef_citerator
itEnd(cstrg
.End());
549 for ( typedef_citerator
it(cstrg
.Begin());
553 if (NOT it
.IsValid())
558 recursive_AssignAsSynonym(rTypedef
.CeId(), rTypedef
);
563 SecondariesCalculator::recursive_AssignAsSynonym( Ce_id i_synonymousTypedefsId
,
564 const Typedef
& i_TypedefToCheck
)
567 nCe
= lhf_Search_CeFromTypeId(i_TypedefToCheck
.DefiningType());
568 if (NOT nCe
.IsValid())
571 rCe
= my_CeStorage()[nCe
];
573 switch (rCe
.AryClass()) // KORR_FUTURE: make this faster, remove switch.
575 case Interface::class_id
:
576 insert_into2sList( rCe
,
577 interface_2s_SynonymTypedefs
,
578 i_synonymousTypedefsId
);
580 case Struct::class_id
:
581 insert_into2sList( rCe
,
582 struct_2s_SynonymTypedefs
,
583 i_synonymousTypedefsId
);
586 insert_into2sList( rCe
,
587 enum_2s_SynonymTypedefs
,
588 i_synonymousTypedefsId
);
590 case Typedef::class_id
:
591 insert_into2sList( rCe
,
592 typedef_2s_SynonymTypedefs
,
593 i_synonymousTypedefsId
);
594 recursive_AssignAsSynonym( i_synonymousTypedefsId
,
595 static_cast< Typedef
& >(rCe
) );
597 // default: do nothing.
602 SecondariesCalculator::recursive_AssignIncludingService( Ce_id i_includingServicesId
,
603 const Service
& i_ServiceToCheckItsIncludes
)
605 Dyn_StdConstIterator
<CommentedRelation
>
607 i_ServiceToCheckItsIncludes
.Get_IncludedServices(pIncludedServices
);
609 for ( StdConstIterator
<CommentedRelation
> &
610 itServ
= *pIncludedServices
;
615 pServ
= lhf_SearchService((*itServ
).Type());
618 insert_into2sUnique( *pServ
,
619 service_2s_IncludingServices
,
620 i_includingServicesId
622 recursive_AssignIncludingService(i_includingServicesId
, *pServ
);
626 assignImplementation_toAServicesInterfaces( i_includingServicesId
,
627 lhf_Search_CeFromTypeId( (*itServ
).Type() ),
628 interface_2s_ExportingServices
);
633 SecondariesCalculator::assign_AsDerivedInterface( const Interface
& i_rDerived
)
635 ary::Dyn_StdConstIterator
<ary::idl::CommentedRelation
>
637 ary::idl::ifc_interface::attr::Get_Bases(pHelp
, i_rDerived
);
639 for ( ary::StdConstIterator
<ary::idl::CommentedRelation
> & it
= *pHelp
;
644 pIfc
= lhf_SearchInterface( (*it
).Type() );
648 insert_into2sList( *pIfc
,
649 interface_2s_Derivations
,
655 SecondariesCalculator::assign_AsDerivedStruct( const Struct
& i_rDerived
)
658 nBase
= i_rDerived
.Base();
662 pParent
= lhf_SearchStruct(nBase
);
665 insert_into2sList( *pParent
,
666 struct_2s_Derivations
,
673 SecondariesCalculator::assign_AsDerivedException( const Exception
& i_rDerived
)
676 nBase
= i_rDerived
.Base();
680 pParent
= lhf_SearchException(nBase
);
683 insert_into2sList( *pParent
,
684 exception_2s_Derivations
,
691 SecondariesCalculator::assignImplementation_toAServicesInterfaces(
694 E_2s_of_Interface i_eList
)
696 if (NOT i_nService
.IsValid())
699 pService
= ary_cast
<Service
>( & my_CeStorage()[i_nService
] );
701 pSglIfcService
= ary_cast
<SglIfcService
>( & my_CeStorage()[i_nService
] );
705 Dyn_StdConstIterator
<CommentedRelation
>
706 pSupportedInterfaces
;
707 pService
->Get_SupportedInterfaces(pSupportedInterfaces
);
709 for ( StdConstIterator
<CommentedRelation
> &
710 itInfc
= *pSupportedInterfaces
;
711 itInfc
.operator bool();
714 recursive_AssignImplementation_toExportedInterface( i_nImpl
,
719 else if (pSglIfcService
!= 0)
721 Type_id nBase
= pSglIfcService
->BaseInterface();
722 recursive_AssignImplementation_toExportedInterface( i_nImpl
,
729 SecondariesCalculator::recursive_AssignImplementation_toExportedInterface(
731 Type_id i_nExportedInterface
,
732 E_2s_of_Interface i_eList
)
735 pIfc
= lhf_SearchInterface(i_nExportedInterface
);
739 insert_into2sUnique( *pIfc
,
742 Dyn_StdConstIterator
<CommentedRelation
>
744 ary::idl::ifc_interface::attr::Get_Bases(pBases
, *pIfc
);
745 for ( StdConstIterator
<CommentedRelation
> & it
= *pBases
;
749 recursive_AssignImplementation_toExportedInterface(i_nService
, (*it
).Type(), i_eList
);
754 SecondariesCalculator::recursive_AssignFunction_toCeAsReturn( Ce_id i_nFunction
,
755 Type_id i_nReturnType
)
758 nCe
= lhf_Search_CeFromTypeId(i_nReturnType
);
759 if (NOT nCe
.IsValid())
763 rCe
= my_CeStorage()[nCe
];
764 switch (rCe
.AryClass()) // KORR_FUTURE: make this faster, remove switch.
766 case Interface::class_id
:
767 insert_into2sList( rCe
,
768 interface_2s_AsReturns
,
771 case Struct::class_id
:
772 insert_into2sList( rCe
,
777 insert_into2sList( rCe
,
781 case Typedef::class_id
:
782 insert_into2sList( rCe
,
783 typedef_2s_AsReturns
,
785 recursive_AssignFunction_toCeAsReturn( i_nFunction
,
786 static_cast< Typedef
& >(rCe
).DefiningType() );
788 // default: do nothing.
793 SecondariesCalculator::recursive_AssignFunction_toCeAsParameter( Ce_id i_nFunction
,
794 Type_id i_nParameterType
)
797 nCe
= lhf_Search_CeFromTypeId(i_nParameterType
);
798 if (NOT nCe
.IsValid())
802 rCe
= my_CeStorage()[nCe
];
803 switch (rCe
.AryClass()) // KORR_FUTURE: make this faster, remove switch.
805 case Interface::class_id
:
806 insert_into2sList( rCe
,
807 interface_2s_AsParameters
,
810 case Struct::class_id
:
811 insert_into2sList( rCe
,
812 struct_2s_AsParameters
,
816 insert_into2sList( rCe
,
817 enum_2s_AsParameters
,
820 case Typedef::class_id
:
821 insert_into2sList( rCe
,
822 typedef_2s_AsParameters
,
824 recursive_AssignFunction_toCeAsParameter( i_nFunction
,
825 static_cast< Typedef
& >(rCe
).DefiningType() );
827 // default: do nothing.
832 SecondariesCalculator::recursive_AssignStructElement_toCeAsDataType( Ce_id i_nDataElement
,
833 Type_id i_nDataType
)
836 nCe
= lhf_Search_CeFromTypeId(i_nDataType
);
837 if (NOT nCe
.IsValid())
841 rCe
= my_CeStorage()[nCe
];
842 switch (rCe
.AryClass()) // KORR_FUTURE: make this faster, remove switch.
844 case Interface::class_id
:
845 insert_into2sList( rCe
,
846 interface_2s_AsDataTypes
,
849 case Struct::class_id
:
850 insert_into2sList( rCe
,
851 struct_2s_AsDataTypes
,
855 insert_into2sList( rCe
,
859 case Typedef::class_id
:
860 insert_into2sList( rCe
,
861 typedef_2s_AsDataTypes
,
863 recursive_AssignFunction_toCeAsParameter( i_nDataElement
,
864 static_cast< Typedef
& >(rCe
).DefiningType() );
866 // default: do nothing.
871 SecondariesCalculator::insert_into2sUnique( CodeEntity
& o_out
,
876 rOut
= o_out
.Secondaries().Access_List(i_listIndex
);
877 if (std::find(rOut
.begin(),rOut
.end(),i_nCe
) != rOut
.end())
879 rOut
.push_back(i_nCe
);
883 SecondariesCalculator::sort_All2s()
886 aIdOrdering(my_CeStorage());
888 for ( stg_iterator it
= my_CeStorage().Begin();
889 it
!= my_CeStorage().End();
893 r2s
= (*it
).Secondaries();
894 int iCount
= r2s
.CountXrefLists();
895 for (int i
= 0; i
< iCount
; ++i
)
897 std::sort( r2s
.Access_List(i
).begin(),
898 r2s
.Access_List(i
).end(),
905 SecondariesCalculator::Read_Links2DevManual( csv::bstream
& i_file
)
907 StreamLock
aLine(300);
908 StreamStr
& rLine
= aLine();
913 E_LinkMode eCurMode
= link2ref
;
916 const char * sLink
= "LINK:";
917 const char * sDescr
= "DESCR:";
918 const char * sTopic
= "TOPIC:";
919 const char * sRef
= "REF:";
920 const UINT8 cMaxASCIINumWhiteSpace
= 32;
922 while (NOT i_file
.eod())
927 rLine
.operator_read_line(i_file
);
929 if ( *rLine
.c_str() >= 'a' )
931 assign_CurLink(rLine
.begin(), sCurLink
, sCurLinkUI
, eCurMode
== link2descr
, lineCount
);
933 else if ( strncmp(rLine
.c_str(), sLink
, strlen(sLink
)) == 0 )
935 sCurLink
= rLine
.c_str()+5;
938 else if ( strncmp(rLine
.c_str(), sDescr
, strlen(sDescr
)) == 0 )
940 sCurLinkUI
= rLine
.c_str()+6;
942 else if ( strncmp(rLine
.c_str(), sTopic
, strlen(sTopic
)) == 0 )
944 eCurMode
= link2descr
;
946 else if ( strncmp(rLine
.c_str(), sRef
, strlen(sRef
)) == 0 )
950 else if (static_cast<UINT8
>(*rLine
.c_str()) > cMaxASCIINumWhiteSpace
)
952 assign_CurLink(rLine
.begin(), sCurLink
, sCurLinkUI
, eCurMode
== link2descr
, lineCount
);
955 // Ignore empty line.
965 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */