1 /////////////////////////////////////////////////////////////////////////////
2 // Name:        No names yet.
3 // Purpose:     To provide a simple _framework_
4 //              for series of source code parsers with
5 //              compatible interfaces
6 // Author:      Aleksandras Gluchovas
7 // Modified by: AG on 28/12/98
8 // Created:     22/09/98
9 // RCS-ID:      $Id: srcparser.h 41718 2006-10-08 14:34:37Z VZ $
10 // Copyright:   (c) Aleskandars Gluchovas
11 // Licence:     wxWindows licence
12 /////////////////////////////////////////////////////////////////////////////
13 
14 #ifndef __SRCPARSER_G__
15 #define __SRCPARSER_G__
16 
17 #if defined( wxUSE_TEMPLATE_STL )
18     #include <vector>
19 
20     #ifdef WIN32
21     #include <bstring.h>
22     #else
23 
24     #include <strclass.h>
25     #include <string.h>
26 
27     #endif
28 
29 #else
30     #include "wx/string.h"
31     #include "wxstlvec.h"
32 
33 #endif
34 
35 #include "markup.h" // markup tags used in spOperator::GetFullName()
36 
37 // these methods are used for debugging only and disappear in the release build
38 #ifdef __WXDEBUG__
39     #define DECLARE_DUMP virtual void DumpThis(const wxString& indent) const;
40 #else
41     #define DECLARE_DUMP
42 #endif
43 
44 // context class list in "inside-out" order :
45 
46 class spContext;
47 
48 class spParameter;
49 class spAttribute;
50 class spOperation;
51 class spEnumeration;
52 class spTypeDef;
53 class spPreprocessorLine;
54 class spClass;
55 class spNameSpace;
56 class spFile;
57 
58 // source context visibilities
59 enum SRC_VISIBLITY_TYPES
60 {
61     SP_VIS_PUBLIC,
62     SP_VIS_PROTECTED,
63     SP_VIS_PRIVATE
64 };
65 
66 // class types
67 enum SP_CLASS_TYPES
68 {
69     SP_CLTYPE_INVALID,
70     SP_CLTYPE_CLASS,
71     SP_CLTYPE_TEMPLATE_CLASS,
72     SP_CLTYPE_STRUCTURE,
73     SP_CLTYPE_UNION,
74     SP_CLTYPE_INTERFACE
75 };
76 
77 // inheritance types
78 enum SP_INHERITANCE_TYPES
79 {
80     SP_INHERIT_VIRTUAL,
81     SP_INHERIT_PUBLIC,
82     SP_INHERIT_PRIVATE
83 };
84 
85 // proprocessor definitions types (specific to C++ code)
86 
87 enum SP_PREP_DEFINITION_TYPES
88 {
89     SP_PREP_DEF_DEFINE_SYMBOL,
90     SP_PREP_DEF_REDEFINE_SYMBOL,
91     SP_PREP_DEF_INCLUDE_FILE,
92     SP_PREP_DEF_OTHER
93 };
94 
95 // common context types
96 
97 #define SP_CTX_UNKNOWN       0x000
98 #define    SP_CTX_FILE          0x001
99 #define    SP_CTX_NAMESPACE     0x002
100 #define    SP_CTX_CLASS         0x004
101 #define SP_CTX_TYPEDEF       0x008
102 #define SP_CTX_PREPROCESSOR  0x010
103 #define SP_CTX_ENUMERATION   0x020
104 #define    SP_CTX_ATTRIBUTE     0x040
105 #define    SP_CTX_OPERATION     0x080
106 #define    SP_CTX_PARAMETER     0x100
107 
108 // other (custom) context codes may be defined elsewere, however they should
109 // not clash with above codes for common type and also should not
110 // exceed 16-bits of in value
111 
112 // masks all context types (up to 16 custom context can be defined)
113 
114 #define SP_CTX_ANY           0xFFFF
115 
116 class spComment;
117 
118 
119 
120 #if defined( wxUSE_TEMPLATE_STL )
121 
122     // context members
123     typedef vector<spContext*> MMemberListT;
124     // comments list
125     typedef vector<spComment*> MCommentListT;
126     // list of parameters
127     typedef vector<spParameter*> MParamListT;
128     // wxString list
129     typedef vector<wxString>   StrListT;
130 
131 #else
132 
133     typedef spContext*   spContextPtrT;
134     typedef spComment*   spCommentPtrT;
135     typedef spParameter* spParameterPtrT;
136     typedef WXSTL_VECTOR_SHALLOW_COPY(spContextPtrT)   MMemberListT;
137     typedef WXSTL_VECTOR_SHALLOW_COPY(spCommentPtrT)   MCommentListT;
138     typedef WXSTL_VECTOR_SHALLOW_COPY(spParameterPtrT) MParamListT;
139     typedef WXSTL_VECTOR_SHALLOW_COPY(wxString)        StrListT;
140 
141 #endif
142 // base class for all visitors of source code contents
143 
144 class spVisitor
145 {
146 protected:
147     bool mSiblingSkipped;
148     bool mChildSkipped;
149     int  mContextMask;
150 
151     spContext* mpCurCxt;
152 
153 public:
154     // methods invoked by context
155 
156     // method invoked from user's controling code
157     // to visit all nodes staring at the given context.
158     // Content is sorted if requrired, see comments
159     // spClass on sorting the class members
160 
161     void VisitAll( spContext& atContext,
162                    bool sortContent = true
163                  );
164 
165     // methods invoked by visitor
166 
167     // goes to the next context in the outter scope
168     // NOTE:: should not be invoked more than once while
169     //        visiting certain context
170 
171     void SkipSiblings();
172 
173     // prevents going down into the contexts contained by
174     // the current context
175     // NOTE:: the same as above
176 
177     void SkipChildren();
178 
179     // can be called only in from visiting procedure
180     void RemoveCurrentContext();
181 
182     // method enables fast filtered traversal
183     // of source content, e.g. collecting only classes,
184     // or only global functions
185 
186     // arg. context - can contain combination of contexts concatinated
187     //           with bitwise OR, e.g. SP_CTX_CLASS | SP_CTX_NAMESPACE
188     //
189     // method can be invoked from the user's controling as well as
190     // from within the visting procedure
191 
192     void SetFilter( int contextMask );
193 
194     // methods should be implemneted by specific visitor:
195 
196     // NOTE:: Do not confuse visiting with parsing, first
197     //        the source is parsed, and than can be visited
198     //        multiple times by variouse visitors (there can
199     //        be more the one visitor visiting content at a time)
200 
VisitFile(spFile & WXUNUSED (fl))201     virtual void VisitFile( spFile& WXUNUSED(fl) ) {}
202 
VisitNameSpace(spNameSpace & WXUNUSED (ns))203     virtual void VisitNameSpace( spNameSpace& WXUNUSED(ns) ) {}
204 
VisitClass(spClass & WXUNUSED (cl))205     virtual void VisitClass( spClass& WXUNUSED(cl) ) {}
206 
VisitEnumeration(spEnumeration & WXUNUSED (en))207     virtual void VisitEnumeration( spEnumeration& WXUNUSED(en) ) {}
208 
VisitTypeDef(spTypeDef & WXUNUSED (td))209     virtual void VisitTypeDef( spTypeDef& WXUNUSED(td) ) {}
210 
VisitPreprocessorLine(spPreprocessorLine & WXUNUSED (pd))211     virtual void VisitPreprocessorLine( spPreprocessorLine& WXUNUSED(pd) ) {}
212 
VisitAttribute(spAttribute & WXUNUSED (attr))213     virtual void VisitAttribute( spAttribute& WXUNUSED(attr) ) {}
214 
VisitOperation(spOperation & WXUNUSED (op))215     virtual void VisitOperation( spOperation& WXUNUSED(op) ) {}
216 
VisitParameter(spParameter & WXUNUSED (param))217     virtual void VisitParameter( spParameter& WXUNUSED(param) ) {}
218 
VisitCustomContext(spContext & WXUNUSED (ctx))219     virtual void VisitCustomContext( spContext& WXUNUSED(ctx) ) {}
220 
~spVisitor()221     virtual ~spVisitor() { }
222 };
223 
224 // stores one section of comments,
225 // multiple sections can be put to geather
226 // and attached to some context
227 
228 class spComment
229 {
230 public:
231     wxString  m_Text;
232     bool      mIsMultiline; // multiline comments ar those with /**/'s
233 
234     // true, if these was an empty empty
235     // line above single line comment
236 
237     bool      mStartsPar;
238 
239 public:
240 
241     bool      IsMultiline() const;
242     bool      StartsParagraph() const;
243 
244     wxString& GetText();
245 
246     // contstant version of GetText()
247     wxString  GetText() const;
248 };
249 
250 // abstract base class for common (to most languages) code
251 // contexts (constructs), e.g file, namespace, class, operation,
252 // etc
253 
254 class spContext
255 {
256 protected:
257     // "linked" list of comments belonging to this context
258     MCommentListT mComments;
259 
260     // NULL, if this is file context
261     MMemberListT   mMembers;
262 
263     // NULL, if this is top-most context
264     spContext*    m_pParent;
265 
266     // points to context object, where the this context
267     // was originally declared, meaning that this object
268     // is redeclaration (or if in the case of operation
269     // this context object most probably referres to the
270     // implemnetation in .cpp file for example)
271 
272     // is NULL, if this object referres to the first occurence
273     // of the context
274 
275     spContext*    mpFirstOccurence;
276 
277     // used, to avoid excessive sorting of context's agreggates
278     bool          mAlreadySorted;
279 
280 public:
281 
282     // source line number, (-1) if unknown
283     int           mSrcLineNo;
284 
285     // offset of context in the source file, (-1) if unknown
286     int           mSrcOffset;
287 
288     // lentgh of the context in characters, (-1) if unknown
289     int           mContextLength;
290 
291     // source line number, in which this cotext ends, (-1) if unknown
292     int           mLastScrLineNo;
293 
294     // fields are valid, if the may contain other contexts nested inside
295     int           mHeaderLength;
296     int           mFooterLength;
297 
298     // zero-based index of the first character of
299     // this context in the source line, (-1) if unknown
300     int           mFirstCharPos;
301 
302     // zero-based index of the first character of
303     // this context in the last source line of this context, (-1) if unknown
304     int           mLastCharPos;
305 
306     // see SRC_VISIBLITY_TYPES enumeration
307     int           mVisibility;
308 
309     // true, if context does not really exist in the source
310     //       but was created by external tools (e.g. forward engineering)
311 
312     bool         mIsVirtualContext;
313     bool         mVirtualContextHasChildren;
314 
315     // body of the context in case (mIsVirtual == true)
316     wxString     mVirtualContextBody;
317     wxString     mVittualContextFooter;
318 
319     // e.g. can be used by documentation generator to store
320     // reference to section object
321     void*         mpUserData;
322 
323 public:
324     // universal identifier of the context (e.g. class name)
325     wxString      m_Name;
326 
327 public:
328     // default constructor
329     spContext();
330 
331     // automatically destorys all aggregated contexts
332     // (thus, it's enought to call destructor of root-context)
333     virtual ~spContext();
334 
335     // see mUererData member;
GetUserData()336     void* GetUserData() { return mpUserData; }
337 
338     // sets untyped pointer to user data
SetUserData(void * pUserData)339     void SetUserData( void* pUserData )
340         { mpUserData = pUserData; }
341 
342     // searches the whole context tree for the cotnexts
343     // which match given masks, pust results into lst array
344     void GetContextList( MMemberListT& lst, int contextMask );
345 
346     // used by default visitor's implementation
347     bool IsSorted();
348 
349     /*** forward/reverse ingineering fecilities ***/
350 
351     bool PositionIsKnown();
352 
353     bool IsVirtualContext();
354 
355     bool VitualContextHasChildren();
356 
357     void SetVirtualContextBody( const wxString& body,
358                                 bool  hasChildren = false,
359                                 const wxString& footer = wxEmptyString );
360 
361     wxString GetVirtualContextBody();
362     wxString GetFooterOfVirtualContextBody();
363 
364     // can be overriden by top-level context classes
365     // to find-out ot the source-fragment of this
366     // context using it's position information
367     virtual wxString GetBody( spContext* pCtx = NULL );
368 
369     virtual wxString GetHeader( spContext* pCtx = NULL );
370 
371     // true, if there is at least one entry
372     // in the comment list of this context
373     bool HasComments();
GetCommentList()374     MCommentListT& GetCommentList() { return mComments; }
GetCommentList()375     const MCommentListT& GetCommentList() const { return mComments; }
376 
377     // should be overriden, if the context supports sorting
378     // of it's members
SortMembers()379     virtual void SortMembers() {}
380 
381     // returns identifier of this context
GetName()382     inline wxString& GetName() { return m_Name; }
383 
384     // returns -1, if souce line # is unknow
GetSourceLineNo()385     inline int GetSourceLineNo() { return mSrcLineNo; }
386 
387     // see comments on mpFirstOccurence member variable
388     bool IsFirstOccurence();
389     spContext* GetFirstOccurence();
390 
391     // returns not-NULL value if this context
392     // is aggregated by another cotnext
393     spContext* GetOutterContext();
394 
395     // perhaps more intuitive alias for `GetOutterContext()'
GetParent()396     inline spContext* GetParent() { return m_pParent; }
397 
398     bool HasOutterContext();
399 
400     // add one aggregate (or child) into this context
401     void AddMember ( spContext* pMember );
402     MMemberListT& GetMembers();
403 
404     // append comment to the comment list decribing
405     // this context
406     void AddComment( spComment* pComment );
407 
408     // returns NULL, if the context with the given
409     // name and type is not contained by this context
410     // and it's children. Children's children are not
411     // searched recursivelly if searchSubMembers is false
412 
413     spContext* FindContext( const wxString& identifier,
414                             int   contextType      = SP_CTX_ANY,
415                             bool  searchSubMembers = true
416                           );
417 
418     // removes this context from it's parent
419     // (NOTE:: context should have an outter cotnext
420     //  to when this method is called, otherwise removal
421     //  will result assertion failure)
422     void RemoveThisContext();
423 
424     // returns true, if this object is aggregated in the file
425     bool IsInFile();
426 
427     // true, if outter context is a namespace
428     bool IsInNameSpace();
429 
430     // true, if outter context is a class
431     bool IsInClass();
432 
433     // true, if outter cotext is an operation (true for "spParameter"s)
434     bool IsInOperation();
435 
436     // true if the context is public
IsPublic()437     bool IsPublic() const { return mVisibility == SP_VIS_PUBLIC; }
438 
439     // NOTE:: method returns not the type of this object
440     //          but the file/namespace/class/operation or file in which this
441     //          attribute is contained. First, check for the type of
442     //        context using the above method.
443 
444     //          Requiering container which does not exist, will result
445     //        in assertion failure
446 
447     spClass&     GetClass();
448     spFile&      GetFile();
449     spNameSpace& GetNameSpace();
450     spOperation& GetOperation();
451 
452     // each new context should override this method
453     // to return it's specific type
GetContextType()454     virtual int GetContextType() const { return SP_CTX_UNKNOWN; }
455 
456     // perhaps more intuitive short-cut
GetType()457     inline int GetType() { return GetContextType(); }
458 
459     // cast this context to the desired type - returns NULL if type is wrong
CastToAttribute()460     spAttribute *CastToAttribute()
461     {
462         return GetContextType() == SP_CTX_ATTRIBUTE ? (spAttribute *)this
463                                                     : NULL;
464     }
465 
466     // derived classes override this to invoke VisitXXX method
467     // which corresponds to the class of specific context,
468     // - this is what the "Visitor" pattern told us ^)
469 
470     // if method is not overriden, then it's probably user-defined
471     // custom context
472 
AcceptVisitor(spVisitor & visitor)473     virtual void AcceptVisitor( spVisitor& visitor )
474 
475         { visitor.VisitCustomContext( *this );    };
476 
477     // called by visitors, to remove given subcontext
478     // of this context object
479     void RemoveChild( spContext* pChild );
480 
481     void RemoveChildren();
482 
483     spContext* GetEnclosingContext( int mask = SP_CTX_ANY );
484 
485 #ifdef __WXDEBUG__
486     virtual void Dump(const wxString& indent) const;
487 #endif  // __WXDEBUG__
488 
489     DECLARE_DUMP
490 };
491 
492 // stores information about single argument of operation
493 
494 class spParameter : public spContext
495 {
496 public:
497     // type of argument (parameter)
498     wxString m_Type;
499 
500     // "stringified" initial value
501     wxString m_InitVal;
502 
503 public:
GetContextType()504     virtual int GetContextType() const { return SP_CTX_PARAMETER; }
505 
AcceptVisitor(spVisitor & visitor)506     virtual void AcceptVisitor( spVisitor& visitor )
507         { visitor.VisitParameter( *this ); }
508 
509     DECLARE_DUMP
510 };
511 
512 
513 // stores information about member(or global) variable
514 
515 class spAttribute : public spContext
516 {
517 public:
518     // type of the attribute
519     wxString m_Type;
520 
521     // it's initial value
522     wxString m_InitVal;
523 
524     // constantness
525     bool   mIsConstant;
526 public:
527 
GetContextType()528     virtual int GetContextType() const { return SP_CTX_ATTRIBUTE; }
529 
AcceptVisitor(spVisitor & visitor)530     virtual void AcceptVisitor( spVisitor& visitor )
531         { visitor.VisitAttribute( *this ); }
532 
533     DECLARE_DUMP
534 };
535 
536 class spOperation : public spContext
537 {
538 public:
539     // type of return value
540     wxString    m_RetType;
541 
542     // argument list
543     //MParamListT mParams;
544 
545     // true, if operation does not modify
546     // the content of the object
547     bool        mIsConstant;
548 
549     // flag, specific to C++
550     bool        mIsVirtual;
551 
552     // true, if definition follows the declaration immediatelly
553     bool        mHasDefinition;
554 
555     // scope if any (e.g. MyClass::MyFunction(), scope stirng is "MyClass" )
556     // usually found along with implementation of the method, which is now skipped
557 
558     wxString    mScope;
559 
560 public:
561     spOperation();
562 
563     // returns full declaration of the operations
564     // (ret val., identifier, arg. list),
565 
566     // arguments are marked up with italic,
567     // default values marked up with bold-italic,
568     // all the rest is marked as bold
569 
570     // NOTE:: this method may be overriden by class
571     //        specific to concrete parser, to provide
572     //        language-dependent reperesnetation of
573     //        operation and it's argumetn list
574     //
575     // the default implementation outputs name in
576     // C++/Java syntax
577 
578     virtual wxString GetFullName(MarkupTagsT tags);
579 
GetContextType()580     virtual int GetContextType() const { return SP_CTX_OPERATION; }
581 
AcceptVisitor(spVisitor & visitor)582     virtual void AcceptVisitor( spVisitor& visitor )
583         { visitor.VisitOperation( *this ); }
584 
585     DECLARE_DUMP
586 };
587 
588 // stores infromation about preprocessor directive
589 
590 class spPreprocessorLine : public spContext
591 {
592 
593 public:
594 
595     // prepocessor statement including '#' and
596     // attached multiple lines with '\' character
597     wxString m_Line;
598 
599     int    mDefType; // see SP_PREP_DEFINITION_TYPES enumeration
600 
601 public:
602 
GetContextType()603     virtual int GetContextType() const { return SP_CTX_PREPROCESSOR; }
604 
GetStatementType()605     virtual int GetStatementType() const { return mDefType; }
606 
607     wxString CPP_GetIncludedFileNeme() const;
608 
AcceptVisitor(spVisitor & visitor)609     virtual void AcceptVisitor( spVisitor& visitor )
610         { visitor.VisitPreprocessorLine( *this ); }
611 
612     DECLARE_DUMP
613 };
614 
615 // stores information about the class
616 
617 class spClass : public spContext
618 {
619 public:
620     // list of superclasses/interfaces
621     StrListT     m_SuperClassNames;
622 
623     // see SP_CLASS_TYPES enumeration
624     int          mClassSubType;
625 
626     // see SP_INHERITANCE_TYPES enumeration
627     int          mInheritanceType;
628 
629     // valid if mClassSubType is SP_CLTYPE_TEMPLATE_CLASS
630     wxString     mTemplateTypes;
631 
632     // true, if it's and interface of abstract base class
633     bool         mIsAbstract;
634 
635 public:
636     // sorts class members in the following order:
637     //
638     // (by "privacy level" - first private, than protected, public)
639     //
640     //     within above set
641     //
642     //       (by member type - attributes first, than methods, nested classes)
643     //
644     //          within above set
645     //
646     //             (by identifier of the member)
647 
648     virtual void SortMembers();
649 
GetContextType()650     virtual int GetContextType() const { return SP_CTX_CLASS; }
651 
AcceptVisitor(spVisitor & visitor)652     virtual void AcceptVisitor( spVisitor& visitor )
653         { visitor.VisitClass( *this ); }
654 
655     DECLARE_DUMP
656 };
657 
658 // stores information about enum statement
659 
660 class spEnumeration  : public spContext
661 {
662 public:
663     wxString m_EnumContent; // full-text content of enumeration
664 
665 public:
GetContextType()666     virtual int GetContextType() const { return SP_CTX_ENUMERATION; }
667 
AcceptVisitor(spVisitor & visitor)668     virtual void AcceptVisitor( spVisitor& visitor )
669         { visitor.VisitEnumeration( *this ); }
670 
671     DECLARE_DUMP
672 };
673 
674 class spTypeDef  : public spContext
675 {
676 public:
677     // the original type which is redefined
678     // by this type definition
679     wxString m_OriginalType;
680 
681 public:
GetContextType()682     virtual int GetContextType() const { return SP_CTX_TYPEDEF; }
683 
AcceptVisitor(spVisitor & visitor)684     virtual void AcceptVisitor( spVisitor& visitor )
685         { visitor.VisitTypeDef( *this ); }
686 
687     DECLARE_DUMP
688 };
689 
690 // NOTE:: files context may be put to other
691 //        file context, resulting in a collection
692 //        of parsed file contexts, with a virtual "superfile"
693 
694 class spFile : public spContext
695 {
696 public:
697     // since file name cannot be determined from
698     // source code, filling in this field is optional
699     wxString m_FileName;
700 
701 public:
GetContextType()702     virtual int GetContextType() const { return SP_CTX_FILE; }
703 
AcceptVisitor(spVisitor & visitor)704     virtual void AcceptVisitor( spVisitor& visitor )
705         { visitor.VisitFile( *this ); }
706 
707     DECLARE_DUMP
708 };
709 
710 //TODO:: comments.
711 
712 class SourceParserPlugin
713 {
714 public:
715     virtual bool CanUnderstandContext( char* cur, char* end, spContext* pOuttterCtx ) = 0;
716     virtual void ParseContext( char* start, char*& cur, char* end, spContext* pOuttterCtx ) = 0;
717 
~SourceParserPlugin()718     virtual ~SourceParserPlugin() { }
719 };
720 
721 // abstract interface for source parsers
722 // which can output parsing results in the
723 // form of context-tree, where each node
724 // should be derivative of spContext, (see
725 // above classes)
726 
727 class SourceParserBase
728 {
729 private:
730     // auto-resizing file buffer, created in ParseFile()
731     // to reuse large heap block for multiple parsings
732 
733     char* mpFileBuf;
734     int   mFileBufSz;
735 
736 protected:
737     SourceParserPlugin* mpPlugin;
738 
739 protected:
740     // value is set in the derived parser classes
741     int mParserStatus;
742 
743 public:
744     SourceParserBase();
745     virtual ~SourceParserBase();
746 
747     // loads entier source file(as text) into memory,
748     // and passes it's contents to ParseAll() method,
749     // memory occupied by source text is released after
750     // parsing is done
751     //
752     // (NOTE:: this is the default implementation),
753 
754     virtual spFile* ParseFile( const char* fname );
755 
756     // should returns the root-node of the created context tree
757     // (user is responsible for releasing it from the heep)
758     // "end" should point to the (last character + 1) of the
759     // source text area
760 
761     virtual spFile* Parse( char* start, char* end ) = 0;
762 
763     // returns parser "status word" (specific to concrete parser)
GetParserStatus()764     int GetParserStatus() { return mParserStatus; }
765 
766     void SetPlugin( SourceParserPlugin* pPlugin );
767 };
768 
769 #endif
770