xref: /AOO41X/main/autodoc/source/display/html/pm_class.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
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 "pm_class.hxx"
30 
31 
32 // NOT FULLY DEFINED SERVICES
33 #include <ary/cpp/c_gate.hxx>
34 #include <ary/cpp/c_class.hxx>
35 #include <ary/cpp/c_tydef.hxx>
36 #include <ary/cpp/cp_ce.hxx>
37 #include <ary/loc/loc_file.hxx>
38 #include <ary/loc/locp_le.hxx>
39 #include <ary/getncast.hxx>
40 #include "hd_chlst.hxx"
41 #include "hd_docu.hxx"
42 #include "hdimpl.hxx"
43 #include "html_kit.hxx"
44 #include "navibar.hxx"
45 #include "opageenv.hxx"
46 #include "pagemake.hxx"
47 #include "strconst.hxx"
48 
49 using namespace adcdisp;
50 
51 using namespace csi;
52 using csi::html::HorizontalLine;
53 using csi::html::LineBreak;
54 using csi::html::Link;
55 using csi::html::Table;
56 using csi::html::TableRow;
57 using csi::html::TableCell;
58 
59 using ary::cpp::CesConstIterator;
60 using ary::doc::OldCppDocu;
61 
62 const char * const C_sTitle_InnerClasses    = "Classes";
63 const char * const C_sTitle_InnerStructs    = "Structs";
64 const char * const C_sTitle_InnerUnions     = "Unions";
65 const char * const C_sTitle_Methods         = "Methods";
66 const char * const C_sTitle_StaticMethods   = "Static Methods";
67 const char * const C_sTitle_Data            = "Data";
68 const char * const C_sTitle_StaticData      = "Static Data";
69 
70 const char * const C_sLabel_StaticOperations    = "static_ops";
71 const char * const C_sLabel_StaticVariables     = "static_vars";
72 
73 const char * const   C_sTitlePublic      = "Public Members";
74 const char * const   C_sTitleProtected   = "Protected Members";
75 const char * const   C_sTitlePrivate     = "Private Members";
76 const char * const   C_sMprTitles[3]     = { C_sTitlePublic,
77                                              C_sTitleProtected,
78                                              C_sTitlePrivate
79                                            };
80 const char * const   C_sSummaryTitlePublic      = "Public Members";
81 const char * const   C_sSummaryTitleProtected   = "Protected Members";
82 const char * const   C_sSummaryTitlePrivate     = "Private Members";
83 const char *
84         C_sMprSummaryTitles[3] =
85         { C_sSummaryTitlePublic, C_sSummaryTitleProtected, C_sSummaryTitlePrivate };
86 const char *
87         C_sMprPrefixes[3] =
88         { "publ_", "prot_", "priv_" };
89 const char *
90         C_sSummaryItems_Titles[PageMaker_Class::cl_MAX] =
91         { C_sTitle_InnerClasses, C_sTitle_InnerStructs, C_sTitle_InnerUnions,
92           C_sTitle_Enums, C_sTitle_Typedefs,
93           C_sTitle_Methods, C_sTitle_StaticMethods, C_sTitle_Data, C_sTitle_StaticData };
94 const char *
95         C_sSummaryItems_Labels[PageMaker_Class::cl_MAX] =
96         { C_sLabel_Classes, C_sLabel_Structs, C_sLabel_Unions,
97           C_sLabel_Enums, C_sLabel_Typedefs,
98           C_sLabel_Operations, C_sLabel_StaticOperations,
99           C_sLabel_Variables, C_sLabel_StaticVariables };
100 
101 
102 const ary::cpp::E_Protection
103         aProt[3] = { ary::cpp::PROTECT_public,
104                      ary::cpp::PROTECT_protected,
105                      ary::cpp::PROTECT_private };
106 
107 
108 PageMaker_Class::PageMaker_Class( PageDisplay &             io_rPage,
109                                   const ary::cpp::Class &   i_rClass )
110     :   SpecializedPageMaker(io_rPage),
111         pMe( &i_rClass ),
112         pChildDisplay( new ChildList_Display(io_rPage.Env(), i_rClass) ),
113         pNavi(0)
114         // pProtectionArea,
115         // bChildLists_Exist
116 {
117     int i_max = 3 * cl_MAX;
118     for (int i = 0; i < i_max; i++)
119     {
120         bChildLists_Exist[i] = false;
121     }  // end for
122 }
123 
124 PageMaker_Class::~PageMaker_Class()
125 {
126 }
127 
128 void
129 PageMaker_Class::MakePage()
130 {
131     pNavi = new NavigationBar( Env(), Me() );
132 
133     Write_NavBar();
134     Write_TopArea();
135     Write_DocuArea();
136     Write_ChildLists();
137 
138     pNavi->Write_SubRows();
139     pNavi = 0;
140 }
141 
142 void
143 PageMaker_Class::Write_NavBar()
144 {
145     NavigationBar   aNavi( Env(), Me() );
146     pNavi->Write( CurOut() );
147     CurOut() << new HorizontalLine;
148 }
149 
150 inline bool
151 IsInterface(const ary::doc::Documentation & i_doc)
152 {
153     const OldCppDocu *
154         doc = Get_CppDocu(i_doc);
155     return doc != 0
156             ?   doc->IsInterface()
157             :   false;
158 }
159 
160 void
161 PageMaker_Class::Write_TopArea()
162 {
163     TemplateClause fTemplateClause;
164     PageTitle_Std fTitle;
165 
166     Page().Write_NameChainWithLinks( Me() );
167 
168     fTemplateClause( CurOut(), Me().TemplateParameters() );
169     fTitle( CurOut(), Get_ClassTypeKey(Me()), Me().LocalName() );
170 
171     CurOut() << new HorizontalLine;
172 
173     Write_BaseHierarchy();
174     Write_DerivedList();
175 
176     CurOut() << new LineBreak;
177 
178     adcdisp::FlagTable
179         aFlags( CurOut(), 4 );
180     aFlags.SetColumn( 0, "virtual",
181                       Me().Virtuality() != ary::cpp::VIRTUAL_none );
182     aFlags.SetColumn( 1, "abstract",
183                       Me().Virtuality() == ary::cpp::VIRTUAL_abstract );
184     aFlags.SetColumn( 2, "interface",
185                       IsInterface(Me().Docu())
186                       OR  Me().Virtuality() == ary::cpp::VIRTUAL_abstract );
187     aFlags.SetColumn( 3, "template",
188                       Me().TemplateParameters().size() > 0 );
189 }
190 
191 void
192 PageMaker_Class::Write_DocuArea()
193 {
194     Docu_Display aDocuShow( Env() );
195 
196     aDocuShow.Assign_Out(CurOut());
197     Me().Accept( aDocuShow );
198     aDocuShow.Unassign_Out();
199 
200     ary::loc::File &
201         rFile = Env().Gate().Locations().Find_File( Me().Location() );
202 
203     adcdisp::ExplanationList
204         aFileText( CurOut() );
205     aFileText.AddEntry("File");
206     aFileText.Def()
207         << rFile.LocalName();
208 
209     CurOut() << new HorizontalLine;
210 }
211 
212 void
213 PageMaker_Class::Write_ChildLists()
214 {
215     int i_max = 3 * cl_MAX;
216     for (int i = 0; i < i_max; i++)
217     {
218         bChildLists_Exist[i] = false;
219     }  // end for
220 
221     csi::html::DefListDefinition &
222             rPublic = Setup_MemberSegment_Out( mp_public );
223     csi::html::DefListDefinition &
224             rProtected = Setup_MemberSegment_Out( mp_protected );
225     csi::html::DefListDefinition &
226             rPrivate = Setup_MemberSegment_Out( mp_private );
227 
228     Write_ChildList_forClasses( rPublic,
229                                 rProtected,
230                                 rPrivate,
231                                 C_sLabel_Classes,
232                                 C_sTitle_InnerClasses,
233                                 ary::cpp::CK_class );
234     Write_ChildList_forClasses( rPublic,
235                                 rProtected,
236                                 rPrivate,
237                                 C_sLabel_Structs,
238                                 C_sTitle_InnerStructs,
239                                 ary::cpp::CK_struct );
240     Write_ChildList_forClasses( rPublic,
241                                 rProtected,
242                                 rPrivate,
243                                 C_sLabel_Unions,
244                                 C_sTitle_InnerUnions,
245                                 ary::cpp::CK_union );
246 
247     Write_ChildList( ary::cpp::Class::SLOT_Enums,
248                      cl_Enums,
249                      C_sLabel_Enums,
250                      C_sTitle_Enums,
251                      rPublic,
252                      rProtected,
253                      rPrivate );
254     Write_ChildList( ary::cpp::Class::SLOT_Typedefs,
255                      cl_Typedefs,
256                      C_sLabel_Typedefs,
257                      C_sTitle_Typedefs,
258                      rPublic,
259                      rProtected,
260                      rPrivate );
261 
262     Write_ChildList( ary::cpp::Class::SLOT_Operations,
263                      cl_Operations,
264                      C_sLabel_Operations,
265                      C_sTitle_Methods,
266                      rPublic,
267                      rProtected,
268                      rPrivate );
269     Write_ChildList( ary::cpp::Class::SLOT_StaticOperations,
270                      cl_StaticOperations,
271                      C_sLabel_StaticOperations,
272                      C_sTitle_StaticMethods,
273                      rPublic,
274                      rProtected,
275                      rPrivate );
276     Write_ChildList( ary::cpp::Class::SLOT_Data,
277                      cl_Data,
278                      C_sLabel_Variables,
279                      C_sTitle_Data,
280                      rPublic,
281                      rProtected,
282                      rPrivate );
283     Write_ChildList( ary::cpp::Class::SLOT_StaticData,
284                      cl_StaticData,
285                      C_sLabel_StaticVariables,
286                      C_sTitle_StaticData,
287                      rPublic,
288                      rProtected,
289                      rPrivate );
290 
291     Create_NaviSubRow(mp_public);       // Also puts out or deletes pPublic.
292     Create_NaviSubRow(mp_protected);    // Also puts out or deletes pProtected.
293     Create_NaviSubRow(mp_private);      // Also puts out or deletes pPrivate.
294 }
295 
296 void
297 PageMaker_Class::Write_ChildList( ary::SlotAccessId   i_nSlot,
298                                   E_ChidList          i_eChildListIndex,
299                                   const char *        i_sLabel,
300                                   const char *        i_sListTitle,
301                                   csi::xml::Element & o_rPublic,
302                                   csi::xml::Element & o_rProtected,
303                                   csi::xml::Element & o_rPrivate )
304 
305 {
306     bool    bPublic_ChildrenExist = false;
307     bool    bProtected_ChildrenExist = false;
308     bool    bPrivate_ChildrenExist = false;
309 
310     ChildList_Display::Area_Result
311             aPublic_Result( bPublic_ChildrenExist, o_rPublic );
312     ChildList_Display::Area_Result
313             aProtected_Result( bProtected_ChildrenExist, o_rProtected );
314     ChildList_Display::Area_Result
315             aPrivate_Result( bPrivate_ChildrenExist, o_rPrivate );
316 
317     String sLabelPublic = ChildListLabel(i_sLabel, mp_public);
318     String sLabelProtected = ChildListLabel(i_sLabel, mp_protected);
319     String sLabelPrivate = ChildListLabel(i_sLabel, mp_private);
320 
321     pChildDisplay->Run_Members( aPublic_Result,
322                                 aProtected_Result,
323                                 aPrivate_Result,
324                                 i_nSlot,
325                                 sLabelPublic,
326                                 sLabelProtected,
327                                 sLabelPrivate,
328                                 i_sListTitle );
329 
330     bChildLists_Exist[i_eChildListIndex]
331                 = bPublic_ChildrenExist;
332     bChildLists_Exist[i_eChildListIndex + cl_MAX]
333                 = bProtected_ChildrenExist;
334     bChildLists_Exist[i_eChildListIndex + 2*cl_MAX]
335                 = bPrivate_ChildrenExist;
336 
337     if (bPublic_ChildrenExist)
338         o_rPublic << new HorizontalLine;
339     if (bProtected_ChildrenExist)
340         o_rProtected << new HorizontalLine;
341     if (bPrivate_ChildrenExist)
342         o_rPrivate << new HorizontalLine;
343 }
344 
345 void
346 PageMaker_Class::Write_ChildList_forClasses( csi::xml::Element &    o_rPublic,
347                                              csi::xml::Element &    o_rProtected,
348                                              csi::xml::Element &    o_rPrivate,
349                                              const char *           i_sLabel,
350                                              const char *           i_sListTitle,
351                                              ary::cpp::E_ClassKey   i_eFilter )
352 {
353     bool    bPublic_ChildrenExist = false;
354     bool    bProtected_ChildrenExist = false;
355     bool    bPrivate_ChildrenExist = false;
356 
357     ChildList_Display::Area_Result
358             aPublic_Result( bPublic_ChildrenExist, o_rPublic );
359     ChildList_Display::Area_Result
360             aProtected_Result( bProtected_ChildrenExist, o_rProtected );
361     ChildList_Display::Area_Result
362             aPrivate_Result( bPrivate_ChildrenExist, o_rPrivate );
363 
364     String sLabelPublic = ChildListLabel(i_sLabel, mp_public);
365     String sLabelProtected = ChildListLabel(i_sLabel, mp_protected);
366     String sLabelPrivate = ChildListLabel(i_sLabel, mp_private);
367 
368     pChildDisplay->Run_MemberClasses( aPublic_Result,
369                                       aProtected_Result,
370                                       aPrivate_Result,
371                                       ary::cpp::Class::SLOT_NestedClasses,
372                                       sLabelPublic,
373                                       sLabelProtected,
374                                       sLabelPrivate,
375                                       i_sListTitle,
376                                       i_eFilter );
377 
378     bChildLists_Exist[int(cl_NestedClasses)+int(i_eFilter)]
379                 = bPublic_ChildrenExist;
380     bChildLists_Exist[int(cl_NestedClasses)+int(i_eFilter) + cl_MAX]
381                 = bProtected_ChildrenExist;
382     bChildLists_Exist[int(cl_NestedClasses)+int(i_eFilter) + 2*cl_MAX]
383                 = bPrivate_ChildrenExist;
384 
385     if (bPublic_ChildrenExist)
386         o_rPublic << new HorizontalLine;
387     if (bProtected_ChildrenExist)
388         o_rProtected << new HorizontalLine;
389     if (bPrivate_ChildrenExist)
390         o_rPrivate << new HorizontalLine;
391 }
392 
393 const char *
394 PageMaker_Class::ChildListLabel( const char * i_sLabel, E_MemberProtection i_eMpr )
395 {
396  	static char sResult[100];
397     strcpy( sResult, C_sMprPrefixes[i_eMpr] );  // SAFE STRCPY (#100211# - checked)
398     strcat( sResult, i_sLabel );                // SAFE STRCAT (#100211# - checked)
399     return sResult;
400 }
401 
402 csi::html::DefListDefinition &
403 PageMaker_Class::Setup_MemberSegment_Out( E_MemberProtection i_eMpr )
404 {
405     html::DefList * pDefList = new html::DefList;
406     pProtectionArea[i_eMpr] = pDefList;
407 
408     pDefList->AddTerm()
409         << new html::ClassAttr("subtitle")
410         >> *new html::Label( C_sMprPrefixes[i_eMpr] )
411                 >> *new html::Headline(3)
412                         << C_sMprTitles[i_eMpr];
413     return pDefList->AddDefinition();
414 }
415 
416 void
417 PageMaker_Class::Create_NaviSubRow( E_MemberProtection i_eMpr )
418 {
419     int nIndexAdd = int(cl_MAX) * int(i_eMpr);
420 
421     bool bEmpty = true;
422     for (int e = 0; e < cl_MAX; e++)
423     {
424         if ( bChildLists_Exist[e + nIndexAdd] )
425         {
426             bEmpty = false;
427             break;
428         }
429     }  // end for
430     if (bEmpty)
431     {
432         pProtectionArea[i_eMpr] = 0;
433         return;
434     }
435     else //
436     {
437         CurOut() << pProtectionArea[i_eMpr].Release();
438     }  // endif
439 
440     pNavi->MakeSubRow( C_sMprSummaryTitles[i_eMpr] );
441     for (int i = 0; i < cl_MAX; i++)
442     {
443         pNavi->AddItem( C_sSummaryItems_Titles[i],
444                         ChildListLabel( C_sSummaryItems_Labels[i], i_eMpr ),
445                         bChildLists_Exist[i+nIndexAdd] );
446     }  // end for
447 }
448 
449 void
450 PageMaker_Class::Write_DerivedList()
451 {
452     adcdisp::ExplanationList
453         aDeriveds( CurOut() );
454     aDeriveds.AddEntry( "Known Derived Classes" );
455 
456     if ( Me().KnownDerivatives().Size() == 0 )
457     {
458         aDeriveds.Def() << "None.";
459         return;
460     }
461 
462     typedef ary::List_Rid  RidList;
463 
464     CesConstIterator
465         itEnd = Me().KnownDerivatives().End();
466     for ( CesConstIterator it = Me().KnownDerivatives().Begin();
467           it != itEnd;
468           ++it )
469     {
470         const ary::cpp::CodeEntity &
471             rCe = Env().Gate().Ces().Find_Ce(*it);
472 
473         aDeriveds.Def()
474             >> *new html::Link( Link2Ce(Env(),rCe) )
475                 << rCe.LocalName();
476         aDeriveds.Def()
477             << new html::LineBreak;
478     }   // end for
479 }
480 
481 
482 // ==============  Creating a classes base hierarchy  ====================== //
483 
484 
485 namespace
486 {
487 
488 class Node
489 {
490   public:
491                         Node(
492                             const ary::cpp::Class &
493                                                 i_rClass,
494                             ary::cpp::Type_id   i_nClassType,
495                             const ary::cpp::Gate &
496                                                 i_rGate,
497                             intt                i_nPositionOffset,
498                             Node *              io_pDerived = 0,
499                             ary::cpp::E_Protection
500                                                 i_eProtection = ary::cpp::PROTECT_global,
501                             bool                i_bVirtual = false );
502                         ~Node();
503 
504     void                FillPositionList(
505                             std::vector< const Node* > &
506                                                 o_rPositionList ) const;
507     void                Write2(
508                             csi::xml::Element & o_rOut,
509                             const OuputPage_Environment &
510                                                 i_rEnv ) const;
511 
512     intt                BaseCount() const       { return nCountBases; }
513     intt                Position() const        { return nPosition; }
514     int                 Xpos() const            { return 3*Position(); }
515     int                 Ypos() const            { return 2*Position(); }
516     const Node *        Derived() const         { return pDerived; }
517 
518   private:
519     typedef std::vector< DYN Node* > BaseList;
520 
521     void                IncrBaseCount();
522 
523     // DATA
524     BaseList            aBases;
525     intt                nCountBases;
526     Node *              pDerived;
527 
528     String              sName;
529     const ary::cpp::Class *
530                         pClass;
531     ary::cpp::Type_id   nClassType;
532     ary::cpp::E_Protection
533                         eProtection;
534     bool                bVirtual;
535 
536     intt                nPosition;
537 };
538 
539 void                WriteNodeHierarchy(
540                         csi::xml::Element & o_rOut,
541                         const OuputPage_Environment &
542                                             i_rEnv,
543                         const Node &        i_rClass );
544 
545 const ary::cpp::Class *
546                     HereFind_Class(
547                         const ary::cpp::Gate &
548                                             i_rGate,
549                         ary::cpp::Type_id   i_nReferingTypeId );
550 
551 }   // anonymous namespace
552 
553 void
554 PageMaker_Class::Write_BaseHierarchy()
555 {
556     adcdisp::ExplanationList aBases( CurOut() );
557     aBases.AddEntry( "Base Classes" );
558 
559     if (   Me().BaseClasses().size() == 0 )
560     {
561         aBases.Def() << "None.";
562     }
563     else
564     {
565         Dyn< Node >
566             pBaseGraph( new Node(Me(), ary::cpp::Type_id(0), Env().Gate(), 0) );
567         WriteNodeHierarchy( aBases.Def(), Env(), *pBaseGraph );
568     }
569 }
570 
571 
572 
573 namespace
574 {
575 
576 void
577 WriteNodeHierarchy( csi::xml::Element &             o_rOut,
578                     const OuputPage_Environment &   i_rEnv,
579                     const Node &                    i_rClass )
580 {
581     typedef const Node *            NodePtr;
582     typedef std::vector<NodePtr>    NodeList;
583 
584     NodeList aPositionList;
585     intt nSize = i_rClass.Position()+1;
586     aPositionList.reserve(nSize);
587     i_rClass.FillPositionList( aPositionList );
588 
589     xml::Element &
590         rPre = o_rOut
591                >> *new xml::AnElement("pre")
592                    << new html::StyleAttr("font-family:monospace;");
593 
594     for ( int line = 0; line < nSize; ++line )
595     {
596         char * sLine1 = new char[2 + line*5];
597         char * sLine2 = new char[1 + line*5];
598         *sLine1 = '\0';
599         *sLine2 = '\0';
600 
601         bool bBaseForThisLineReached = false;
602      	for ( int col = 0; col < line; ++col )
603         {
604             intt nDerivPos = aPositionList[col]->Derived()->Position();
605 
606             if ( nDerivPos >= line )
607                 strcat(sLine1, "  |  ");
608             else
609                 strcat(sLine1, "     ");
610 
611             if ( nDerivPos > line )
612             {
613                 strcat(sLine2, "  |  ");
614             }
615             else if ( nDerivPos == line )
616             {
617                 if (bBaseForThisLineReached)
618                     strcat(sLine2, "--+--");
619                 else
620                 {
621                     bBaseForThisLineReached = true;
622                     strcat(sLine2, "  +--");
623                 }
624             }
625             else // nDerivPos < line
626             {
627                 if (bBaseForThisLineReached)
628                     strcat(sLine2, "-----");
629                 else
630                     strcat(sLine2, "     ");
631             }
632         }  // end for (col)
633         strcat(sLine1,"\n");
634         rPre
635             << sLine1
636             << sLine2;
637         delete [] sLine1;
638         delete [] sLine2;
639 
640         aPositionList[line]->Write2( rPre, i_rEnv );
641         rPre << "\n";
642     }   // end for (line)
643 }
644 
645 const ary::cpp::Class *
646 HereFind_Class( const ary::cpp::Gate & i_rGate,
647                 ary::cpp::Type_id      i_nReferingTypeId )
648 {
649     const ary::cpp::CodeEntity *
650         pCe = i_rGate.Search_RelatedCe( i_nReferingTypeId );
651 
652     if ( pCe != 0 )
653     {
654 		if  ( ary::is_type<ary::cpp::Class>(*pCe) )
655         {
656 			return ary::ary_cast<ary::cpp::Class>(pCe);
657         }
658 		else if ( ary::is_type<ary::cpp::Typedef>(*pCe) )
659 		{
660 			const ary::cpp::Typedef *
661 				pTydef = ary::ary_cast<ary::cpp::Typedef>(pCe);
662 			return  HereFind_Class( i_rGate, pTydef->DescribingType() );
663 		}
664 	}
665 
666     static const ary::cpp::Class aClassNull_( "Base class not found",
667 											  ary::cpp::Ce_id(0),
668 											  ary::cpp::PROTECT_global,
669 											  ary::loc::Le_id(0),
670 											  ary::cpp::CK_class );
671     return &aClassNull_;
672 }
673 
674 
675 
676 //*********************        Node        ***********************//
677 
678 Node::Node( const ary::cpp::Class &         i_rClass,
679             ary::cpp::Type_id               i_nClassType,
680             const ary::cpp::Gate &          i_rGate,
681             intt                            i_nPositionOffset,
682             Node *                          io_pDerived,
683             ary::cpp::E_Protection          i_eProtection,
684             bool                            i_bVirtual )
685     :   aBases(),
686         nCountBases(0),
687         pDerived(io_pDerived),
688         pClass(&i_rClass),
689         nClassType(i_nClassType),
690         eProtection(i_eProtection),
691         bVirtual(i_bVirtual),
692         nPosition(i_nPositionOffset)
693 {
694     typedef ary::cpp::List_Bases  BList;
695 
696     for ( BList::const_iterator it = i_rClass.BaseClasses().begin();
697           it != i_rClass.BaseClasses().end();
698           ++it )
699     {
700         const ary::cpp::Class *
701                 pBaseClass = HereFind_Class( i_rGate, (*it).nId );
702 
703         Dyn<Node>
704             pBase( new Node(*pBaseClass,
705                             (*it).nId,
706                             i_rGate,
707                             nPosition,
708                             this,
709                             (*it).eProtection,
710                             (*it).eVirtuality == ary::cpp::VIRTUAL_virtual)
711                  );
712         IncrBaseCount();
713         nPosition += pBase->BaseCount() + 1;
714         aBases.push_back( pBase.Release() );
715     }   // end for
716 }
717 
718 Node::~Node()
719 {
720 }
721 
722 void
723 Node::FillPositionList( std::vector< const Node* > & o_rPositionList ) const
724 {
725     for ( BaseList::const_iterator it = aBases.begin();
726           it != aBases.end();
727           ++it )
728     {
729         (*it)->FillPositionList(o_rPositionList);
730     }  // end for
731 
732 	if( o_rPositionList.size() != uintt(Position()) )
733     {
734 		csv_assert(false);
735     }
736     o_rPositionList.push_back(this);
737 }
738 
739 void
740 Node::Write2( csi::xml::Element &           o_rOut,
741               const OuputPage_Environment & i_rEnv ) const
742 {
743     if ( Derived() == 0 )
744     {
745         o_rOut
746             >> *new xml::AnElement("span")
747                 << new html::ClassAttr("btself")
748                 << pClass->LocalName();
749         return;
750     }
751 
752     csi::xml::Element *
753         pOut = & ( o_rOut >> *new xml::AnElement("span") );
754     switch ( eProtection )
755     {
756  	    case ary::cpp::PROTECT_public:
757  	                if (bVirtual)
758                         *pOut << new html::ClassAttr("btvpubl");
759                     else
760                         *pOut << new html::ClassAttr("btpubl");
761                     break;
762         case ary::cpp::PROTECT_protected:
763  	                if (bVirtual)
764                         *pOut << new html::ClassAttr("btvprot");
765                     else
766                         *pOut << new html::ClassAttr("btprot");
767                     break;
768         case ary::cpp::PROTECT_private:
769  	                if (bVirtual)
770                         *pOut << new html::ClassAttr("btvpriv");
771                     else
772                         *pOut << new html::ClassAttr("btpriv");
773                     break;
774         default:    // do nothing.
775                     ;
776     }   // end switch
777 
778     csi::xml::Element & rOut = *pOut;
779 
780     Get_LinkedTypeText( rOut, i_rEnv, nClassType, false );
781     rOut << " (";
782     if ( bVirtual )
783         rOut << "virtual ";
784     switch ( eProtection )
785     {
786      	case ary::cpp::PROTECT_public:
787                     rOut << "public)";
788                     break;
789      	case ary::cpp::PROTECT_protected:
790                     rOut << "protected)";
791                     break;
792      	case ary::cpp::PROTECT_private:
793                     rOut << "private)";
794                     break;
795         default:    // do nothing.
796                     ;
797     }   // end switch
798 }
799 
800 void
801 Node::IncrBaseCount()
802 {
803     ++nCountBases;
804     if (pDerived != 0)
805         pDerived->IncrBaseCount();
806 }
807 
808 
809 }   // anonymous namespace
810 
811 
812