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