Code::Blocks  SVN r11506
nativeparser_base.h
Go to the documentation of this file.
1 /*
2  * This file is part of the Code::Blocks IDE and licensed under the GNU General Public License, version 3
3  * http://www.gnu.org/licenses/gpl-3.0.html
4  */
5 
6 #ifndef NATIVEPARSERBASE_H
7 #define NATIVEPARSERBASE_H
8 
9 #if wxCHECK_VERSION(3, 0, 0)
10 #include <wx/wxcrt.h> // wxIsalnum
11 #endif
12 #include <wx/string.h>
13 
14 #include <map>
15 #include <queue>
16 
17 #include "parser/token.h"
18 #include "parser/tokentree.h"
19 
21 extern bool s_DebugSmartSense;
22 
24 {
25 public:
28  {
34  };
35 
38  {
44  };
45 
74  {
78 
80  void Clear()
81  {
82  component = wxEmptyString;
83  tokenType = pttUndefined;
84  tokenOperatorType = otOperatorUndefined;
85  }
86  };
87 
90 
92  virtual ~NativeParserBase();
93 
94 protected:
95 
97  void Reset();
98 
113  size_t FindAIMatches(TokenTree* tree,
114  std::queue<ParserComponent> components,
115  TokenIdxSet& result,
116  int parentTokenIdx = -1,
117  bool isPrefix = false,
118  bool caseSensitive = false,
119  bool use_inheritance = true,
120  short int kindMask = 0xFFFF,
121  TokenIdxSet* search_scope = 0);
122 
140  const TokenIdxSet& procResult,
141  TokenIdxSet& scopeResult);
142 
146  void CleanupSearchScope(TokenTree* tree,
147  TokenIdxSet* searchScope);
148 
159  void GetCallTipHighlight(const wxString& calltip,
160  int* start,
161  int* end,
162  int typedCommas);
163 
167  int FindFunctionOpenParenthesis(const wxString& calltip);
168 
206 
216  unsigned int FindCCTokenStart(const wxString& line);
217 
229  wxString GetNextCCToken(const wxString& line,
230  unsigned int& startAt,
231  OperatorType& tokenOperatorType);
232 
239  void RemoveLastFunctionChildren(TokenTree* tree, int& lastFuncTokenIdx);
240 
246  size_t BreakUpComponents(const wxString& actual,
247  std::queue<ParserComponent>& components);
248 
303  size_t ResolveExpression(TokenTree* tree,
304  std::queue<ParserComponent> components,
305  const TokenIdxSet& searchScope,
306  TokenIdxSet& result,
307  bool caseSense = true,
308  bool isPrefix = false);
309 
317  void ResolveOperator(TokenTree* tree,
318  const OperatorType& tokenOperatorType,
319  const TokenIdxSet& tokens,
320  const TokenIdxSet& searchScope,
321  TokenIdxSet& result);
322 
328  size_t ResolveActualType(TokenTree* tree,
329  wxString searchText,
330  const TokenIdxSet& searchScope,
331  TokenIdxSet& result);
332 
338  void ResolveTemplateMap(TokenTree* tree,
339  const wxString& searchStr,
340  const TokenIdxSet& actualTypeScope,
341  TokenIdxSet& initialScope);
342 
349  void AddTemplateAlias(TokenTree* tree,
350  const int& id,
351  const TokenIdxSet& actualTypeScope,
352  TokenIdxSet& initialScope);
353 
365  size_t GenerateResultSet(TokenTree* tree,
366  const wxString& target,
367  int parentIdx,
368  TokenIdxSet& result,
369  bool caseSens = true,
370  bool isPrefix = false,
371  short int kindMask = 0xFFFF);
372 
379  size_t GenerateResultSet(TokenTree* tree,
380  const wxString& target,
381  const TokenIdxSet& ptrParentID,
382  TokenIdxSet& result,
383  bool caseSens = true,
384  bool isPrefix = false,
385  short int kindMask = 0xFFFF);
386 
394  bool IsAllocator(TokenTree* tree,
395  const int& id);
396 
405  bool DependsOnAllocator(TokenTree* tree,
406  const int& id);
407 
413  void CollectSearchScopes(const TokenIdxSet& searchScope,
414  TokenIdxSet& actualTypeScope,
415  TokenTree* tree);
416 
432  const TokenIdxSet& tokens,
433  size_t curLine,
434  const wxString& file);
435 
449  void ComputeCallTip(TokenTree* tree,
450  const TokenIdxSet& tokens,
451  wxArrayString& items);
452 
456  bool PrettyPrintToken(TokenTree* tree,
457  const Token* token,
458  wxString& result,
459  bool isRoot = true);
460 
461  // convenient static funcs for fast access and improved readability
462 
463  // count commas in lineText (nesting parentheses)
464  static int CountCommas(const wxString& lineText, int start)
465  {
466  int commas = 0;
467  int nest = 0;
468  while (true)
469  {
470  wxChar c = lineText.GetChar(start++);
471  if (c == '\0')
472  break;
473  else if (c == '(')
474  ++nest;
475  else if (c == ')')
476  --nest;
477  else if (c == ',' && nest == 1)
478  ++commas;
479  }
480  return commas;
481  }
482 
489  static bool InsideToken(int startAt, const wxString& line)
490  {
491  return ( (startAt >= 0)
492  && ((size_t)startAt < line.Len())
493  && ( (wxIsalnum(line.GetChar(startAt)))
494  || (line.GetChar(startAt) == '_') ) );
495  }
496 
504  static int BeginOfToken(int startAt, const wxString& line)
505  {
506  while ( (startAt >= 0)
507  && ((size_t)startAt < line.Len())
508  && ( (wxIsalnum(line.GetChar(startAt)))
509  || (line.GetChar(startAt) == '_') ) )
510  --startAt;
511  return startAt;
512  }
513  static int BeforeToken(int startAt, const wxString& line)
514  {
515  if ( (startAt > 0)
516  && ((size_t)startAt < line.Len() + 1)
517  && ( (wxIsalnum(line.GetChar(startAt - 1)))
518  || (line.GetChar(startAt - 1) == '_') ) )
519  --startAt;
520  return startAt;
521  }
522 
531  static bool IsOperatorEnd(int startAt, const wxString& line)
532  {
533  return ( (startAt > 0)
534  && ((size_t)startAt < line.Len())
535  && ( ( (line.GetChar(startAt) == '>')
536  && (line.GetChar(startAt - 1) == '-') )
537  || ( (line.GetChar(startAt) == ':')
538  && (line.GetChar(startAt - 1) == ':') ) ) );
539  }
540  static bool IsOperatorPointer(int startAt, const wxString& line)
541  {
542  return ( (startAt > 0)
543  && ((size_t)startAt < line.Len())
544  && ( ( (line.GetChar(startAt) == '>')
545  && (line.GetChar(startAt - 1) == '-') )));
546  }
547 
549  // FIXME (ollydbg#1#): should be startAt+1 < line.Len()?
550  static bool IsOperatorBegin(int startAt, const wxString& line)
551  {
552  return ( (startAt >= 0)
553  && ((size_t)startAt < line.Len())
554  && ( ( (line.GetChar(startAt ) == '-')
555  && (line.GetChar(startAt + 1) == '>') )
556  || ( (line.GetChar(startAt) == ':')
557  && (line.GetChar(startAt + 1) == ':') ) ) );
558  }
559 
561  static bool IsOperatorDot(int startAt, const wxString& line)
562  {
563  return ( (startAt >= 0)
564  && ((size_t)startAt < line.Len())
565  && (line.GetChar(startAt) == '.') );
566  }
567 
579  static int BeforeWhitespace(int startAt, const wxString& line)
580  {
581  while ( (startAt >= 0)
582  && ((size_t)startAt < line.Len())
583  && ( (line.GetChar(startAt) == ' ')
584  || (line.GetChar(startAt) == '\t') ) )
585  --startAt;
586  return startAt;
587  }
588 
598  static int AfterWhitespace(int startAt, const wxString& line)
599  {
600  if (startAt < 0)
601  startAt = 0;
602  while ( ((size_t)startAt < line.Len())
603  && ( (line.GetChar(startAt) == ' ')
604  || (line.GetChar(startAt) == '\t') ) )
605  ++startAt;
606  return startAt;
607  }
608 
613  static bool IsOpeningBracket(int startAt, const wxString& line)
614  {
615  return ( ((size_t)startAt < line.Len())
616  && ( (line.GetChar(startAt) == '(')
617  || (line.GetChar(startAt) == '[') ) );
618  }
619 
621  static bool IsClosingBracket(int startAt, const wxString& line)
622  {
623  return ( (startAt >= 0)
624  && ( (line.GetChar(startAt) == ')')
625  || (line.GetChar(startAt) == ']') ) );
626  }
627 
628 protected:
629 
630 private:
631  // Helper utilities called only by GenerateResultSet!
632  // No critical section needed! All functions that call these functions,
633  // should already entered a critical section.
634 
643  bool AddChildrenOfUnnamed(TokenTree* tree, const Token* parent, TokenIdxSet& result)
644  {
645  if ( ( (parent->m_TokenKind & (tkClass | tkEnum)) != 0 )
646  && parent->m_IsAnonymous == true )
647  {
648  // add all its children
649  for (TokenIdxSet::const_iterator it = parent->m_Children.begin();
650  it != parent->m_Children.end(); ++it)
651  {
652  Token* tokenChild = tree->at(*it);
653  if ( tokenChild
654  && (parent->m_TokenKind == tkClass || tokenChild->m_Scope != tsPrivate) )
655  {
656  // NOTE: recurse (eg: class A contains struct contains union or enum)
657  if ( !AddChildrenOfUnnamed(tree, tokenChild, result) )
658  {
659  result.insert(*it);
660  AddChildrenOfEnum(tree, tokenChild, result);
661  }
662  }
663  }
664  return true;
665  }
666  return false;
667  }
668 
669  bool AddChildrenOfEnum(TokenTree* tree, const Token* parent, TokenIdxSet& result)
670  {
671  if (parent->m_TokenKind == tkEnum)
672  {
673  // add all its children
674  for (TokenIdxSet::const_iterator it = parent->m_Children.begin();
675  it != parent->m_Children.end(); ++it)
676  {
677  Token* tokenChild = tree->at(*it);
678  if (tokenChild && tokenChild->m_Scope != tsPrivate)
679  result.insert(*it);
680  }
681 
682  return true;
683  }
684  return false;
685  }
686 
695  bool IsChildOfUnnamedOrEnum(TokenTree* tree, const int targetIdx, const int parentIdx)
696  {
697  if (targetIdx == parentIdx)
698  return true;
699  if (parentIdx == -1)
700  return false;
701 
702  Token* parent = tree->at(parentIdx);
703  if (parent && (parent->m_TokenKind & tkClass))
704  {
705  // loop all children of the parent token
706  for (TokenIdxSet::const_iterator it = parent->m_Children.begin();
707  it != parent->m_Children.end(); ++it)
708  {
709  Token* token = tree->at(*it);
710  // an unnamed class is much similar like the enum
711  if (token && (((token->m_TokenKind & tkClass)
712  && (token->m_IsAnonymous == true))
713  || (token->m_TokenKind & tkEnum)))
714  {
715  // if target token matches on child, we can return success
716  // other wise, we try to see the target token matches child's child.
717  if ((targetIdx == (*it)) || IsChildOfUnnamedOrEnum(tree, targetIdx, (*it)))
718  return true;
719  }
720  }
721  }
722  return false;
723  }
724 
725 
727  void AddConstructors(TokenTree *tree, const TokenIdxSet& source, TokenIdxSet& dest);
728 
729  // for GenerateResultSet()
730  bool MatchText(const wxString& text, const wxString& target, bool caseSens, bool isPrefix)
731  {
732  if (isPrefix && target.IsEmpty())
733  return true;
734  if (!isPrefix)
735  return text.CompareTo(target.wx_str(), caseSens ? wxString::exact : wxString::ignoreCase) == 0;
736  // isPrefix == true
737  if (caseSens)
738  return text.StartsWith(target);
739  return text.Upper().StartsWith(target.Upper());
740  }
741 
742  // for GenerateResultSet()
743  bool MatchType(TokenKind kind, short int kindMask)
744  {
745  return kind & kindMask;
746  }
747 
748 private:
750  std::map<wxString, wxString> m_TemplateMap;
751 };
752 
753 #endif // NATIVEPARSERBASE_H
void ResolveTemplateMap(TokenTree *tree, const wxString &searchStr, const TokenIdxSet &actualTypeScope, TokenIdxSet &initialScope)
resolve template map [formal parameter] to [actual parameter]
size_t GenerateResultSet(TokenTree *tree, const wxString &target, int parentIdx, TokenIdxSet &result, bool caseSens=true, bool isPrefix=false, short int kindMask=0xFFFF)
Generate the matching results under the Parent Token index set.
static bool IsOperatorPointer(int startAt, const wxString &line)
static bool IsOperatorDot(int startAt, const wxString &line)
check whether line[startAt] is a dot character
class or struct
Definition: token.h:37
size_t ResolveExpression(TokenTree *tree, std::queue< ParserComponent > components, const TokenIdxSet &searchScope, TokenIdxSet &result, bool caseSense=true, bool isPrefix=false)
A statement(expression) is expressed by a ParserComponent queue We do a match from the left of the qu...
virtual ~NativeParserBase()
Destructor.
Token * at(int idx)
Definition: tokentree.h:51
ParserComponent m_LastComponent
bool m_IsAnonymous
Is anonymous token? (e.g.
Definition: token.h:254
bool AddChildrenOfEnum(TokenTree *tree, const Token *parent, TokenIdxSet &result)
wxString GetNextCCToken(const wxString &line, unsigned int &startAt, OperatorType &tokenOperatorType)
helper function to read the next CCToken, begin from the startAt, this point to a non-space character...
static bool IsOperatorBegin(int startAt, const wxString &line)
check if startAt point to "->" or "::" operator
void CleanupSearchScope(TokenTree *tree, TokenIdxSet *searchScope)
remove all the container tokens in the token index set.
bool MatchText(const wxString &text, const wxString &target, bool caseSens, bool isPrefix)
void FindCurrentFunctionScope(TokenTree *tree, const TokenIdxSet &procResult, TokenIdxSet &scopeResult)
if the expression return the container tokens, which are the parent of the expression.
size_t BreakUpComponents(const wxString &actual, std::queue< ParserComponent > &components)
break a statement to several ParserComponents, and store them in a queue.
a container class to hold all the Tokens getting from parsing stage
Definition: tokentree.h:37
TokenIdxSet m_Children
if it is a class kind token, then it contains all the member tokens
Definition: token.h:268
static bool IsOpeningBracket(int startAt, const wxString &line)
Test whether the current character is a &#39;(&#39; or &#39;[&#39;.
size_t FindAIMatches(TokenTree *tree, std::queue< ParserComponent > components, TokenIdxSet &result, int parentTokenIdx=-1, bool isPrefix=false, bool caseSensitive=false, bool use_inheritance=true, short int kindMask=0xFFFF, TokenIdxSet *search_scope=0)
Artificial Intelligence Matching.
bool s_DebugSmartSense
debug only variable, used to print the AI match related log message
bool MatchType(TokenKind kind, short int kindMask)
int FindFunctionOpenParenthesis(const wxString &calltip)
Finds the position of the opening parenthesis marking the beginning of the params.
TokenScope m_Scope
public? private? protected?
Definition: token.h:231
bool AddChildrenOfUnnamed(TokenTree *tree, const Token *parent, TokenIdxSet &result)
collect child tokens of the specified token, the specified token must be unnamed. ...
int GetTokenFromCurrentLine(TokenTree *tree, const TokenIdxSet &tokens, size_t curLine, const wxString &file)
used to get the correct token index in current line, e.g.
void Reset()
Init cc search member variables.
wxUSE_UNICODE_dependent wxChar
void RemoveLastFunctionChildren(TokenTree *tree, int &lastFuncTokenIdx)
Remove the last function&#39;s children, when doing codecompletion in a function body, the function body up to the caret position was parsed, and the local variables defined in the function were recorded as the function&#39;s children.
bool PrettyPrintToken(TokenTree *tree, const Token *token, wxString &result, bool isRoot=true)
For ComputeCallTip() No critical section needed in this recursive function! All functions that call t...
wxString GetCCToken(wxString &line, ParserTokenType &tokenType, OperatorType &tokenOperatorType)
helper function to split the statement
a symbol found in the parsed files, it can be many kinds, such as a variable, a class and so on...
Definition: token.h:82
std::set< int, std::less< int > > TokenIdxSet
Definition: token.h:16
size_t ResolveActualType(TokenTree *tree, wxString searchText, const TokenIdxSet &searchScope, TokenIdxSet &result)
Get the Type information of the searchText string.
static int AfterWhitespace(int startAt, const wxString &line)
search from left to right, move the cursor to the first character after the space ...
static bool IsClosingBracket(int startAt, const wxString &line)
check the current char (line[startAt]) is either &#39;)&#39; or &#39;]&#39;
std::map< wxString, wxString > m_TemplateMap
OperatorType
the delimiter separating two Parser Component, See ParserComponent struct for more details ...
const wxStringCharType * wx_str() const
static int CountCommas(const wxString &lineText, int start)
wxString wxEmptyString
bool DependsOnAllocator(TokenTree *tree, const int &id)
Test if token with this id depends on allocator class.
void ComputeCallTip(TokenTree *tree, const TokenIdxSet &tokens, wxArrayString &items)
call tips are tips when you are entering some functions, such as you have a class definition ...
static bool IsOperatorEnd(int startAt, const wxString &line)
check startAt is at some character like:
bool wxIsalnum(const wxUniChar &c)
static int BeginOfToken(int startAt, const wxString &line)
go to the first character of the identifier, e.g
static int BeforeToken(int startAt, const wxString &line)
enum
Definition: token.h:40
bool IsEmpty() const
wxString Upper() const
size_t Len() const
TokenKind m_TokenKind
See TokenKind class.
Definition: token.h:234
static bool InsideToken(int startAt, const wxString &line)
check whether the line[startAt] point to the identifier
unsigned int FindCCTokenStart(const wxString &line)
helper function to split the statement
ParserTokenType
divide a statement to several pieces(parser component), each component has a type member ...
a long statement can be divided to a ParserComponent chain.
bool StartsWith(const wxString &prefix, wxString *rest=NULL) const
static int BeforeWhitespace(int startAt, const wxString &line)
move to the char before whitespace and tabs, e.g.
void AddConstructors(TokenTree *tree, const TokenIdxSet &source, TokenIdxSet &dest)
loop on the input Token index set (source), add all its public constructors to output Token index set...
void GetCallTipHighlight(const wxString &calltip, int *start, int *end, int typedCommas)
Returns the start and end of the call-tip highlight region.
wxUniChar GetChar(size_t n) const
void AddTemplateAlias(TokenTree *tree, const int &id, const TokenIdxSet &actualTypeScope, TokenIdxSet &initialScope)
add template parameter, get the actual parameter from the formal parameter list
bool IsAllocator(TokenTree *tree, const int &id)
Test if token with this id is allocator class.
bool IsChildOfUnnamedOrEnum(TokenTree *tree, const int targetIdx, const int parentIdx)
check to see if the token is an unnamed class or enum under the parent token
void ResolveOperator(TokenTree *tree, const OperatorType &tokenOperatorType, const TokenIdxSet &tokens, const TokenIdxSet &searchScope, TokenIdxSet &result)
used to solve the overloaded operator functions return type
void CollectSearchScopes(const TokenIdxSet &searchScope, TokenIdxSet &actualTypeScope, TokenTree *tree)
Collect search scopes, add the searchScopes&#39;s parent scope.
NativeParserBase()
Constructor.
TokenKind
Definition: token.h:29