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