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
46class spContext;
47
48class spParameter;
49class spAttribute;
50class spOperation;
51class spEnumeration;
52class spTypeDef;
53class spPreprocessorLine;
54class spClass;
55class spNameSpace;
56class spFile;
57
58// source context visibilities
59enum SRC_VISIBLITY_TYPES
60{
61    SP_VIS_PUBLIC,
62    SP_VIS_PROTECTED,
63    SP_VIS_PRIVATE
64};
65
66// class types
67enum 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
78enum 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
87enum 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
116class 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
144class spVisitor
145{
146protected:
147    bool mSiblingSkipped;
148    bool mChildSkipped;
149    int  mContextMask;
150
151    spContext* mpCurCxt;
152
153public:
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
201    virtual void VisitFile( spFile& WXUNUSED(fl) ) {}
202
203    virtual void VisitNameSpace( spNameSpace& WXUNUSED(ns) ) {}
204
205    virtual void VisitClass( spClass& WXUNUSED(cl) ) {}
206
207    virtual void VisitEnumeration( spEnumeration& WXUNUSED(en) ) {}
208
209    virtual void VisitTypeDef( spTypeDef& WXUNUSED(td) ) {}
210
211    virtual void VisitPreprocessorLine( spPreprocessorLine& WXUNUSED(pd) ) {}
212
213    virtual void VisitAttribute( spAttribute& WXUNUSED(attr) ) {}
214
215    virtual void VisitOperation( spOperation& WXUNUSED(op) ) {}
216
217    virtual void VisitParameter( spParameter& WXUNUSED(param) ) {}
218
219    virtual void VisitCustomContext( spContext& WXUNUSED(ctx) ) {}
220
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
228class spComment
229{
230public:
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
239public:
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
254class spContext
255{
256protected:
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
280public:
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
323public:
324    // universal identifier of the context (e.g. class name)
325    wxString      m_Name;
326
327public:
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;
336    void* GetUserData() { return mpUserData; }
337
338    // sets untyped pointer to user data
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();
374    MCommentListT& GetCommentList() { return mComments; }
375    const MCommentListT& GetCommentList() const { return mComments; }
376
377    // should be overriden, if the context supports sorting
378    // of it's members
379    virtual void SortMembers() {}
380
381    // returns identifier of this context
382    inline wxString& GetName() { return m_Name; }
383
384    // returns -1, if souce line # is unknow
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()'
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
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
454    virtual int GetContextType() const { return SP_CTX_UNKNOWN; }
455
456    // perhaps more intuitive short-cut
457    inline int GetType() { return GetContextType(); }
458
459    // cast this context to the desired type - returns NULL if type is wrong
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
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
494class spParameter : public spContext
495{
496public:
497    // type of argument (parameter)
498    wxString m_Type;
499
500    // "stringified" initial value
501    wxString m_InitVal;
502
503public:
504    virtual int GetContextType() const { return SP_CTX_PARAMETER; }
505
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
515class spAttribute : public spContext
516{
517public:
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;
526public:
527
528    virtual int GetContextType() const { return SP_CTX_ATTRIBUTE; }
529
530    virtual void AcceptVisitor( spVisitor& visitor )
531        { visitor.VisitAttribute( *this ); }
532
533    DECLARE_DUMP
534};
535
536class spOperation : public spContext
537{
538public:
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
560public:
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
580    virtual int GetContextType() const { return SP_CTX_OPERATION; }
581
582    virtual void AcceptVisitor( spVisitor& visitor )
583        { visitor.VisitOperation( *this ); }
584
585    DECLARE_DUMP
586};
587
588// stores infromation about preprocessor directive
589
590class spPreprocessorLine : public spContext
591{
592
593public:
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
601public:
602
603    virtual int GetContextType() const { return SP_CTX_PREPROCESSOR; }
604
605    virtual int GetStatementType() const { return mDefType; }
606
607    wxString CPP_GetIncludedFileNeme() const;
608
609    virtual void AcceptVisitor( spVisitor& visitor )
610        { visitor.VisitPreprocessorLine( *this ); }
611
612    DECLARE_DUMP
613};
614
615// stores information about the class
616
617class spClass : public spContext
618{
619public:
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
635public:
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
650    virtual int GetContextType() const { return SP_CTX_CLASS; }
651
652    virtual void AcceptVisitor( spVisitor& visitor )
653        { visitor.VisitClass( *this ); }
654
655    DECLARE_DUMP
656};
657
658// stores information about enum statement
659
660class spEnumeration  : public spContext
661{
662public:
663    wxString m_EnumContent; // full-text content of enumeration
664
665public:
666    virtual int GetContextType() const { return SP_CTX_ENUMERATION; }
667
668    virtual void AcceptVisitor( spVisitor& visitor )
669        { visitor.VisitEnumeration( *this ); }
670
671    DECLARE_DUMP
672};
673
674class spTypeDef  : public spContext
675{
676public:
677    // the original type which is redefined
678    // by this type definition
679    wxString m_OriginalType;
680
681public:
682    virtual int GetContextType() const { return SP_CTX_TYPEDEF; }
683
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
694class spFile : public spContext
695{
696public:
697    // since file name cannot be determined from
698    // source code, filling in this field is optional
699    wxString m_FileName;
700
701public:
702    virtual int GetContextType() const { return SP_CTX_FILE; }
703
704    virtual void AcceptVisitor( spVisitor& visitor )
705        { visitor.VisitFile( *this ); }
706
707    DECLARE_DUMP
708};
709
710//TODO:: comments.
711
712class SourceParserPlugin
713{
714public:
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
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
727class SourceParserBase
728{
729private:
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
736protected:
737    SourceParserPlugin* mpPlugin;
738
739protected:
740    // value is set in the derived parser classes
741    int mParserStatus;
742
743public:
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)
764    int GetParserStatus() { return mParserStatus; }
765
766    void SetPlugin( SourceParserPlugin* pPlugin );
767};
768
769#endif
770