1 
2 #include "calledbydict.h"
3 
4 #ifndef CB_PRECOMP
5     #include <wx/string.h>
6     #include <wx/arrstr.h>
7 #endif
8 #include <set>
9 
10 #include "tokenf.h"
11 #include "submoduletokenf.h"
12 
CalledByDict()13 CalledByDict::CalledByDict()
14 {
15 }
16 
~CalledByDict()17 CalledByDict::~CalledByDict()
18 {
19     std::map<wxString,std::list<TokenF*>*>::iterator it;
20 
21     for (it = m_NamesDict.begin(); it != m_NamesDict.end(); ++it)
22         delete(it->second);
23 }
24 
Build(TokensArrayF * allTokens)25 void CalledByDict::Build(TokensArrayF* allTokens)
26 {
27     std::set<wxString> definedNames;
28     int tokenMask = tkSubroutine | tkFunction | tkInterface | tkProcedure | tkModule | tkSubmodule;
29     FindChildrenNames(allTokens, tokenMask, definedNames);
30     FillCalledByDict(allTokens, definedNames);
31 }
32 
FindChildrenNames(TokensArrayF * tokens,int tokenMask,std::set<wxString> & definedNames)33 void CalledByDict::FindChildrenNames(TokensArrayF* tokens, int tokenMask, std::set<wxString> &definedNames)
34 {
35     for (size_t i=0; i<tokens->GetCount(); i++)
36     {
37         if (tokens->Item(i)->m_TokenKind & tokenMask)
38         {
39             TokenF* pTok = tokens->Item(i);
40             if (definedNames.count(pTok->m_Name) == 0)
41                 definedNames.insert(pTok->m_Name);
42         }
43         if (tokens->Item(i)->m_Children.GetCount() > 0)
44             FindChildrenNames(&tokens->Item(i)->m_Children, tokenMask, definedNames);
45     }
46 }
47 
FillCalledByDict(TokensArrayF * tokens,std::set<wxString> & definedNames)48 void CalledByDict::FillCalledByDict(TokensArrayF* tokens, std::set<wxString> &definedNames)
49 {
50     const int tokenCallMask = tkCallFunction | tkCallSubroutine;
51     const int subfunMask = tkFunction | tkSubroutine;
52     const int procMask = tkProcedure | tkProcedureFinal;
53     const int useMask = tkUse | tkSubmodule;
54     for (size_t i=0; i<tokens->GetCount(); i++)
55     {
56         TokenF* pTok = tokens->Item(i);
57         if (pTok->m_TokenKind & tokenCallMask ||
58             (pTok->m_TokenKind & subfunMask && pTok->m_pParent->m_TokenKind == tkInterfaceExplicit) ||
59             (pTok->m_TokenKind == tkOther && pTok->m_pParent->m_TokenKind == tkInterface) ||
60             (pTok->m_TokenKind & procMask && pTok->m_pParent->m_TokenKind == tkType) ||
61              pTok->m_TokenKind & useMask)
62         {
63             wxString name;
64             int idx = pTok->m_Name.Find('%', true);
65             if (idx != wxNOT_FOUND)
66             {
67                 // called type-bound procedure
68                 name = pTok->m_Name.Mid(idx+1);
69             }
70             else if (pTok->m_TokenKind == tkProcedure)
71             {
72                 if (!pTok->m_PartLast.IsEmpty())
73                     name = pTok->m_PartLast;
74                 else
75                     name = pTok->m_Name;
76             }
77             else if (pTok->m_TokenKind == tkSubmodule)
78             {
79                 SubmoduleTokenF* submod = static_cast<SubmoduleTokenF*>(pTok);
80                 if (submod->m_ParentSubmoduleName.IsEmpty())
81                 {
82                     name = submod->m_AncestorModuleName;
83                 }
84                 else
85                 {
86                     name = submod->m_AncestorModuleName + _T(":") + submod->m_ParentSubmoduleName;
87                 }
88             }
89             else
90                 name = pTok->m_Name;
91 
92             if (definedNames.count(name) > 0)
93             {
94                 if (m_NamesDict.count(name) == 0)
95                 {
96                     std::list<TokenF*>* tokList = new std::list<TokenF*>;
97                     tokList->push_back(pTok);
98                     m_NamesDict[name] = tokList;
99                 }
100                 else
101                 {
102                     std::list<TokenF*>* tokList = m_NamesDict[name];
103                     tokList->push_back(pTok);
104                 }
105             }
106         }
107         if (tokens->Item(i)->m_Children.GetCount() > 0)
108             FillCalledByDict(&tokens->Item(i)->m_Children, definedNames);
109     }
110 }
111 
GetCallingTokens(const wxString & name)112 std::list<TokenF*>* CalledByDict::GetCallingTokens(const wxString& name)
113 {
114     if (m_NamesDict.count(name) == 0)
115         return NULL;
116 
117     return m_NamesDict[name];
118 }
119 
120 
121