1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
30 #include "i2s_calculator.hxx"
32 // NOT FULLY DEFINED SERVICES
35 #include <cosv/file.hxx>
36 #include <ary/qualiname.hxx>
37 #include <ary/idl/i_enum.hxx>
38 #include <ary/idl/i_exception.hxx>
39 #include <ary/idl/i_function.hxx>
40 #include <ary/idl/i_gate.hxx>
41 #include <ary/idl/i_interface.hxx>
42 #include <ary/idl/ik_interface.hxx>
43 #include <ary/idl/i_module.hxx>
44 #include <ary/idl/i_property.hxx>
45 #include <ary/idl/i_service.hxx>
46 #include <ary/idl/i_singleton.hxx>
47 #include <ary/idl/i_siservice.hxx>
48 #include <ary/idl/i_sisingleton.hxx>
49 #include <ary/idl/i_struct.hxx>
50 #include <ary/idl/i_structelem.hxx>
51 #include <ary/idl/i_typedef.hxx>
52 #include <ary/idl/ip_ce.hxx>
53 #include <ary/idl/ip_type.hxx>
54 #include <ary/namesort.hxx>
55 #include <nametreenode.hxx>
56 #include "i_nnfinder.hxx"
58 #include "ia_type.hxx"
60 #include "is_type.hxx"
62 #include "it_explicit.hxx"
63 #include "it_sequence.hxx"
64 #include "it_xnameroom.hxx"
74 SecondariesCalculator::SearchCe4Type(Type_id i_type
)
77 ce
= lhf_Search_CeFromTypeId(i_type
);
79 return ary_cast
<DEST
>(& my_CeStorage()[ce
]);
84 typedef stg::const_iterator
<CodeEntity
> stg_citerator
;
85 typedef stg::iterator
<CodeEntity
> stg_iterator
;
87 typedef stg::filter_iterator
<CodeEntity
,Interface
>
90 typedef stg::filter_iterator
<Type
,ExplicitType
>
91 explicittype_iterator
;
93 typedef ary::stg::const_filter_iterator
<CodeEntity
,Typedef
>
98 SecondariesCalculator::lhf_SearchService( Type_id i_nType
)
100 return SearchCe4Type
<Service
>(i_nType
);
104 SecondariesCalculator::lhf_SearchInterface( Type_id i_nType
)
106 return SearchCe4Type
<Interface
>(i_nType
);
110 SecondariesCalculator::lhf_SearchStruct( Type_id i_nType
)
112 return SearchCe4Type
<Struct
>(i_nType
);
116 SecondariesCalculator::lhf_SearchException( Type_id i_nType
)
118 return SearchCe4Type
<Exception
>(i_nType
);
121 inline const Ce_Storage
&
122 SecondariesCalculator::my_CeStorage() const
124 csv_assert(pCes
!= 0);
125 return pCes
->Storage();
128 inline const Type_Storage
&
129 SecondariesCalculator::my_TypeStorage() const
131 csv_assert(pTypes
!= 0);
132 return pTypes
->Storage();
136 SecondariesCalculator::my_CeStorage()
138 csv_assert(pCes
!= 0);
139 return pCes
->Storage();
142 inline Type_Storage
&
143 SecondariesCalculator::my_TypeStorage()
145 csv_assert(pTypes
!= 0);
146 return pTypes
->Storage();
150 SecondariesCalculator::insert_into2sList( CodeEntity
& o_out
,
153 { o_out
.Secondaries().Access_List(i_listIndex
).push_back(i_nCe
); }
156 SecondariesCalculator::SecondariesCalculator( CeAdmin
& i_ces
,
157 TypeAdmin
& i_types
)
163 SecondariesCalculator::~SecondariesCalculator()
169 SecondariesCalculator::CheckAllInterfaceBases()
172 rGlobalNamespace
= pCes
->GlobalNamespace();
174 aXInterface("::com::sun::star::uno::XInterface","::");
177 rType
= pTypes
->CheckIn_Type( aXInterface
,
179 rGlobalNamespace
.CeId(),
182 nTypeXInterface
= rType
.TypeId();
184 rExplType
= ary_cast
<ExplicitType
>(rType
);
186 nCeXInterface
= lhf_Search_CeForType(rExplType
);
188 interface_iterator
itEnd( my_CeStorage().End() );
189 for ( interface_iterator
it( my_CeStorage().BeginUnreserved() );
193 if (NOT it
.IsValid())
198 if ( NOT rInterface
.HasBase() // According to UNO IDL syntax, an interface without base has com::sun::star::uno::XInterface as base.
199 AND rInterface
.CeId() != nCeXInterface
) // XInterface must not be base of itself.
201 rInterface
.Add_Base(nTypeXInterface
, 0);
207 SecondariesCalculator::Connect_Types2Ces()
209 explicittype_iterator
itEnd( my_TypeStorage().End() );
210 for ( explicittype_iterator
it( my_TypeStorage().BeginUnreserved() );
214 if (NOT it
.IsValid())
218 rType
= ary_cast
<ExplicitType
>(*it
);
220 nRelatedCe
= lhf_Search_CeForType(rType
);
221 if (nRelatedCe
.IsValid())
224 pNew
= new Ce_Type(nRelatedCe
, rType
.TemplateParameters());
225 my_TypeStorage().Replace_Entity( rType
.TypeId(),
232 SecondariesCalculator::Gather_CrossReferences()
236 for ( stg_iterator it
= my_CeStorage().Begin();
237 it
!= my_CeStorage().End();
240 (*it
).Accept( static_cast< SPInst_asHost
& >(*this) );
248 SecondariesCalculator::Make_Links2DeveloperManual(
249 const String
& i_devman_reffilepath
)
252 aFile(i_devman_reffilepath
, csv::CFM_READ
);
257 Read_Links2DevManual(aFile
);
270 struct OrderCeIdsByName
273 const Ce_Storage
& i_storage
)
274 : rStorage(i_storage
),
280 return aNameComparison( rStorage
[i_ce1
].LocalName(),
281 rStorage
[i_ce2
].LocalName() );
285 const Ce_Storage
& rStorage
;
286 LesserName aNameComparison
;
295 SecondariesCalculator::do_Process( const Service
& i_rData
)
298 rService
= ary_cast
<Service
>(i_rData
);
301 assignImplementation_toAServicesInterfaces( rService
.CeId(),
303 interface_2s_ExportingServices
);
304 // Services and their interfaces:
305 recursive_AssignIncludingService(rService
.CeId(), rService
);
309 SecondariesCalculator::do_Process( const Interface
& i_rData
)
311 assign_AsDerivedInterface( ary_cast
<Interface
>(i_rData
) );
315 SecondariesCalculator::do_Process( const Struct
& i_rData
)
317 assign_AsDerivedStruct( ary_cast
<Struct
>(i_rData
) );
321 SecondariesCalculator::do_Process( const Exception
& i_rData
)
323 assign_AsDerivedException( ary_cast
<Exception
>(i_rData
) );
327 SecondariesCalculator::do_Process( const Typedef
& )
330 // Find out what was meant here ???
333 // rTypedef = ary_cast<Typedef>(i_rData);
337 SecondariesCalculator::do_Process( const Singleton
& i_rData
)
340 rSingleton
= ary_cast
<Singleton
>(i_rData
);
343 pServ
= lhf_SearchService(rSingleton
.AssociatedService());
346 insert_into2sUnique( *pServ
,
347 service_2s_InstantiatingSingletons
,
352 assignImplementation_toAServicesInterfaces( rSingleton
.CeId(),
353 lhf_Search_CeFromTypeId(rSingleton
.AssociatedService()),
354 interface_2s_ExportingSingletons
);
358 SecondariesCalculator::do_Process( const SglIfcService
& i_rData
)
360 const SglIfcService
&
361 rSglIfcService
= ary_cast
<SglIfcService
>(i_rData
);
363 assignImplementation_toAServicesInterfaces( rSglIfcService
.CeId(),
364 rSglIfcService
.CeId(),
365 interface_2s_ExportingServices
);
369 SecondariesCalculator::do_Process( const SglIfcSingleton
& i_rData
)
371 const SglIfcSingleton
&
372 rSglIfcSingleton
= ary_cast
<SglIfcSingleton
>(i_rData
);
374 Type_id nBase
= rSglIfcSingleton
.BaseInterface();
375 recursive_AssignImplementation_toExportedInterface( rSglIfcSingleton
.CeId(),
377 interface_2s_ExportingSingletons
);
381 SecondariesCalculator::do_Process( const Function
& i_rData
)
384 rFunction
= ary_cast
<Function
>(i_rData
);
386 recursive_AssignFunction_toCeAsReturn(rFunction
.CeId(), rFunction
.ReturnType());
388 for ( Function::ParamList::const_iterator itp
= rFunction
.Parameters().begin();
389 itp
!= rFunction
.Parameters().end();
392 recursive_AssignFunction_toCeAsParameter(rFunction
.CeId(), (*itp
).Type());
395 for ( Function::ExceptionList::const_iterator itx
= rFunction
.Exceptions().begin();
396 itx
!= rFunction
.Exceptions().end();
400 pX
= lhf_SearchException(*itx
);
403 insert_into2sUnique(*pX
, exception_2s_RaisingFunctions
, rFunction
.CeId());
409 SecondariesCalculator::do_Process( const StructElement
& i_rData
)
411 const StructElement
&
412 rStructElement
= ary_cast
<StructElement
>(i_rData
);
414 recursive_AssignStructElement_toCeAsDataType(rStructElement
.CeId(), rStructElement
.Type());
418 SecondariesCalculator::do_Process( const Property
& i_rData
)
421 rProperty
= ary_cast
<Property
>(i_rData
);
423 recursive_AssignStructElement_toCeAsDataType(rProperty
.CeId(), rProperty
.Type());
427 SecondariesCalculator::lhf_Search_CeForType( const ExplicitType
& i_rType
) const
429 const ExplicitNameRoom
&
430 rExplicitNameRoom
= ary_cast
<ExplicitNameRoom
>(
431 my_TypeStorage()[i_rType
.NameRoom()] );
433 rNodeFinder( my_CeStorage(),
434 rExplicitNameRoom
.NameChain_Begin(),
435 rExplicitNameRoom
.NameChain_End(),
438 if ( rExplicitNameRoom
.IsAbsolute() )
441 rGlobalNamespace
= ary_cast
<Module
>(
442 my_CeStorage()[predefined::ce_GlobalNamespace
]);
443 return Search_SubTree( rGlobalNamespace
,
449 rStartModule
= ary_cast
<Module
>(
450 my_CeStorage()[i_rType
.ModuleOfOccurrence()]);
451 Ce_id ret
= Search_SubTree_UpTillRoot( rStartModule
,
454 } // endif (rExplicitNameRoom.IsAbsolute()) else
458 SecondariesCalculator::lhf_Search_CeFromTypeId( Type_id i_nType
) const
460 if (NOT i_nType
.IsValid())
463 pType
= ary_cast
<Ce_Type
>( & my_TypeStorage()[i_nType
] );
470 SecondariesCalculator::assign_CurLink( char * i_text
,
471 const String
& i_link
,
472 const String
& i_linkUI
,
476 csv_assert(i_text
!= 0);
478 const ary::idl::Module
*
479 pModule
= & ary_cast
<Module
>(
480 my_CeStorage()[predefined::ce_GlobalNamespace
]);
482 char * pPastNext
= 0;
483 char * pNext
= i_text
;
485 (pPastNext
= strstr(pNext
,".")) != 0;
486 pNext
= pPastNext
+ 1 )
488 String
sNext(pNext
, pPastNext
-pNext
);
489 Ce_id nModule
= pModule
->Search_Name(sNext
);
490 if (nModule
.IsValid())
492 pModule
= ary_cast
<Module
>( & my_CeStorage()[nModule
] );
501 Cerr() << "Warning: Invalid line nr. "
503 << " in DevelopersGuide reference file:\n"
504 << reinterpret_cast< const char* >(i_text
)
511 pPastNext
= strchr(pNext
,':');
512 bool bMember
= pPastNext
!= 0;
513 String
sCe( pNext
, (bMember
? csv::str::size(pPastNext
-pNext
) : csv::str::maxsize
) );
516 // String sMember(bMember ? pPastNext+1, "");
518 Ce_id nCe
= pModule
->Search_Name(sCe
);
519 if (NOT nCe
.IsValid())
521 Cerr() << "Warning: Invalid line nr. "
523 << " in DevelopersGuide reference file:\n"
524 << reinterpret_cast< const char* >(i_text
)
531 rCe
= my_CeStorage()[nCe
];
535 rCe
.Secondaries().Add_Link2DescriptionInManual(i_link
, i_linkUI
);
537 rCe
.Secondaries().Add_Link2RefInManual(i_link
, i_linkUI
);
543 // Provisorial just doing nothing (or may be
544 // adding a link at main Ces lists).
546 // rCe.Secondaries().Add_Link2DescriptionInManual(i_link);
548 // rCe.Secondaries().Add_Link2RefInManual(i_link);
553 SecondariesCalculator::gather_Synonyms()
556 cstrg
= my_CeStorage();
557 typedef_citerator
itEnd(cstrg
.End());
558 for ( typedef_citerator
it(cstrg
.Begin());
562 if (NOT it
.IsValid())
567 recursive_AssignAsSynonym(rTypedef
.CeId(), rTypedef
);
572 SecondariesCalculator::recursive_AssignAsSynonym( Ce_id i_synonymousTypedefsId
,
573 const Typedef
& i_TypedefToCheck
)
576 nCe
= lhf_Search_CeFromTypeId(i_TypedefToCheck
.DefiningType());
577 if (NOT nCe
.IsValid())
580 rCe
= my_CeStorage()[nCe
];
582 switch (rCe
.AryClass()) // KORR_FUTURE: make this faster, remove switch.
584 case Interface::class_id
:
585 insert_into2sList( rCe
,
586 interface_2s_SynonymTypedefs
,
587 i_synonymousTypedefsId
);
589 case Struct::class_id
:
590 insert_into2sList( rCe
,
591 struct_2s_SynonymTypedefs
,
592 i_synonymousTypedefsId
);
595 insert_into2sList( rCe
,
596 enum_2s_SynonymTypedefs
,
597 i_synonymousTypedefsId
);
599 case Typedef::class_id
:
600 insert_into2sList( rCe
,
601 typedef_2s_SynonymTypedefs
,
602 i_synonymousTypedefsId
);
603 recursive_AssignAsSynonym( i_synonymousTypedefsId
,
604 static_cast< Typedef
& >(rCe
) );
606 // default: do nothing.
611 SecondariesCalculator::recursive_AssignIncludingService( Ce_id i_includingServicesId
,
612 const Service
& i_ServiceToCheckItsIncludes
)
614 Dyn_StdConstIterator
<CommentedRelation
>
616 i_ServiceToCheckItsIncludes
.Get_IncludedServices(pIncludedServices
);
618 for ( StdConstIterator
<CommentedRelation
> &
619 itServ
= *pIncludedServices
;
624 pServ
= lhf_SearchService((*itServ
).Type());
627 insert_into2sUnique( *pServ
,
628 service_2s_IncludingServices
,
629 i_includingServicesId
631 recursive_AssignIncludingService(i_includingServicesId
, *pServ
);
635 assignImplementation_toAServicesInterfaces( i_includingServicesId
,
636 lhf_Search_CeFromTypeId( (*itServ
).Type() ),
637 interface_2s_ExportingServices
);
642 SecondariesCalculator::assign_AsDerivedInterface( const Interface
& i_rDerived
)
644 ary::Dyn_StdConstIterator
<ary::idl::CommentedRelation
>
646 ary::idl::ifc_interface::attr::Get_Bases(pHelp
, i_rDerived
);
648 for ( ary::StdConstIterator
<ary::idl::CommentedRelation
> & it
= *pHelp
;
653 pIfc
= lhf_SearchInterface( (*it
).Type() );
657 insert_into2sList( *pIfc
,
658 interface_2s_Derivations
,
664 SecondariesCalculator::assign_AsDerivedStruct( const Struct
& i_rDerived
)
667 nBase
= i_rDerived
.Base();
671 pParent
= lhf_SearchStruct(nBase
);
674 insert_into2sList( *pParent
,
675 struct_2s_Derivations
,
682 SecondariesCalculator::assign_AsDerivedException( const Exception
& i_rDerived
)
685 nBase
= i_rDerived
.Base();
689 pParent
= lhf_SearchException(nBase
);
692 insert_into2sList( *pParent
,
693 exception_2s_Derivations
,
700 SecondariesCalculator::assignImplementation_toAServicesInterfaces(
703 E_2s_of_Interface i_eList
)
705 if (NOT i_nService
.IsValid())
708 pService
= ary_cast
<Service
>( & my_CeStorage()[i_nService
] );
710 pSglIfcService
= ary_cast
<SglIfcService
>( & my_CeStorage()[i_nService
] );
714 Dyn_StdConstIterator
<CommentedRelation
>
715 pSupportedInterfaces
;
716 pService
->Get_SupportedInterfaces(pSupportedInterfaces
);
718 for ( StdConstIterator
<CommentedRelation
> &
719 itInfc
= *pSupportedInterfaces
;
720 itInfc
.operator bool();
723 recursive_AssignImplementation_toExportedInterface( i_nImpl
,
728 else if (pSglIfcService
!= 0)
730 Type_id nBase
= pSglIfcService
->BaseInterface();
731 recursive_AssignImplementation_toExportedInterface( i_nImpl
,
738 SecondariesCalculator::recursive_AssignImplementation_toExportedInterface(
740 Type_id i_nExportedInterface
,
741 E_2s_of_Interface i_eList
)
744 pIfc
= lhf_SearchInterface(i_nExportedInterface
);
748 insert_into2sUnique( *pIfc
,
751 Dyn_StdConstIterator
<CommentedRelation
>
753 ary::idl::ifc_interface::attr::Get_Bases(pBases
, *pIfc
);
754 for ( StdConstIterator
<CommentedRelation
> & it
= *pBases
;
758 recursive_AssignImplementation_toExportedInterface(i_nService
, (*it
).Type(), i_eList
);
763 SecondariesCalculator::recursive_AssignFunction_toCeAsReturn( Ce_id i_nFunction
,
764 Type_id i_nReturnType
)
767 nCe
= lhf_Search_CeFromTypeId(i_nReturnType
);
768 if (NOT nCe
.IsValid())
772 rCe
= my_CeStorage()[nCe
];
773 switch (rCe
.AryClass()) // KORR_FUTURE: make this faster, remove switch.
775 case Interface::class_id
:
776 insert_into2sList( rCe
,
777 interface_2s_AsReturns
,
780 case Struct::class_id
:
781 insert_into2sList( rCe
,
786 insert_into2sList( rCe
,
790 case Typedef::class_id
:
791 insert_into2sList( rCe
,
792 typedef_2s_AsReturns
,
794 recursive_AssignFunction_toCeAsReturn( i_nFunction
,
795 static_cast< Typedef
& >(rCe
).DefiningType() );
797 // default: do nothing.
802 SecondariesCalculator::recursive_AssignFunction_toCeAsParameter( Ce_id i_nFunction
,
803 Type_id i_nParameterType
)
806 nCe
= lhf_Search_CeFromTypeId(i_nParameterType
);
807 if (NOT nCe
.IsValid())
811 rCe
= my_CeStorage()[nCe
];
812 switch (rCe
.AryClass()) // KORR_FUTURE: make this faster, remove switch.
814 case Interface::class_id
:
815 insert_into2sList( rCe
,
816 interface_2s_AsParameters
,
819 case Struct::class_id
:
820 insert_into2sList( rCe
,
821 struct_2s_AsParameters
,
825 insert_into2sList( rCe
,
826 enum_2s_AsParameters
,
829 case Typedef::class_id
:
830 insert_into2sList( rCe
,
831 typedef_2s_AsParameters
,
833 recursive_AssignFunction_toCeAsParameter( i_nFunction
,
834 static_cast< Typedef
& >(rCe
).DefiningType() );
836 // default: do nothing.
841 SecondariesCalculator::recursive_AssignStructElement_toCeAsDataType( Ce_id i_nDataElement
,
842 Type_id i_nDataType
)
845 nCe
= lhf_Search_CeFromTypeId(i_nDataType
);
846 if (NOT nCe
.IsValid())
850 rCe
= my_CeStorage()[nCe
];
851 switch (rCe
.AryClass()) // KORR_FUTURE: make this faster, remove switch.
853 case Interface::class_id
:
854 insert_into2sList( rCe
,
855 interface_2s_AsDataTypes
,
858 case Struct::class_id
:
859 insert_into2sList( rCe
,
860 struct_2s_AsDataTypes
,
864 insert_into2sList( rCe
,
868 case Typedef::class_id
:
869 insert_into2sList( rCe
,
870 typedef_2s_AsDataTypes
,
872 recursive_AssignFunction_toCeAsParameter( i_nDataElement
,
873 static_cast< Typedef
& >(rCe
).DefiningType() );
875 // default: do nothing.
880 SecondariesCalculator::insert_into2sUnique( CodeEntity
& o_out
,
885 rOut
= o_out
.Secondaries().Access_List(i_listIndex
);
886 if (std::find(rOut
.begin(),rOut
.end(),i_nCe
) != rOut
.end())
888 rOut
.push_back(i_nCe
);
892 SecondariesCalculator::sort_All2s()
895 aIdOrdering(my_CeStorage());
897 for ( stg_iterator it
= my_CeStorage().Begin();
898 it
!= my_CeStorage().End();
902 r2s
= (*it
).Secondaries();
903 int iCount
= r2s
.CountXrefLists();
904 for (int i
= 0; i
< iCount
; ++i
)
906 std::sort( r2s
.Access_List(i
).begin(),
907 r2s
.Access_List(i
).end(),
914 SecondariesCalculator::Read_Links2DevManual( csv::bstream
& i_file
)
916 StreamLock
aLine(300);
917 StreamStr
& rLine
= aLine();
922 E_LinkMode eCurMode
= link2ref
;
925 const char * sLink
= "LINK:";
926 const char * sDescr
= "DESCR:";
927 const char * sTopic
= "TOPIC:";
928 const char * sRef
= "REF:";
929 const UINT8 cMaxASCIINumWhiteSpace
= 32;
931 while (NOT i_file
.eod())
936 rLine
.operator_read_line(i_file
);
938 if ( *rLine
.c_str() >= 'a' )
940 assign_CurLink(rLine
.begin(), sCurLink
, sCurLinkUI
, eCurMode
== link2descr
, lineCount
);
942 else if ( strncmp(rLine
.c_str(), sLink
, strlen(sLink
)) == 0 )
944 sCurLink
= rLine
.c_str()+5;
947 else if ( strncmp(rLine
.c_str(), sDescr
, strlen(sDescr
)) == 0 )
949 sCurLinkUI
= rLine
.c_str()+6;
951 else if ( strncmp(rLine
.c_str(), sTopic
, strlen(sTopic
)) == 0 )
953 eCurMode
= link2descr
;
955 else if ( strncmp(rLine
.c_str(), sRef
, strlen(sRef
)) == 0 )
959 else if (static_cast<UINT8
>(*rLine
.c_str()) > cMaxASCIINumWhiteSpace
)
961 assign_CurLink(rLine
.begin(), sCurLink
, sCurLinkUI
, eCurMode
== link2descr
, lineCount
);
964 // Ignore empty line.
974 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */