1 /*
2 * This file is part of the FortranProject plugin for Code::Blocks IDE
3 * and licensed under the GNU General Public License, version 3
4 * http://www.gnu.org/licenses/gpl-3.0.html
5 */
6
7 #include "keywordsparserf.h"
8
9 #include <sdk.h>
10 #ifndef CB_PRECOMP
11 #include <wx/tokenzr.h>
12 #include <wx/string.h>
13 #include <wx/arrstr.h>
14 #include <wx/file.h>
15
16 #include <globals.h>
17 #include <cbstyledtextctrl.h>
18 #include <configmanager.h>
19 #include <logmanager.h>
20 #endif
21
22 #include "parserthreadf.h"
23
KeywordsParserF()24 KeywordsParserF::KeywordsParserF():
25 m_Parser(false)
26 {
27 m_IsDone = false;
28 wxString filename = ConfigManager::GetDataFolder() + _T("/images/fortranproject/fortran_procedures.f90");
29 if (!wxFileExists(filename))
30 {
31 Manager::Get()->GetLogManager()->Log(_T("FortranProject plugin error: file ")+filename+_T(" was not found."));
32 return;
33 }
34 m_Parser.Reparse(filename, filename, fsfFree);
35
36 TokensArrayF* pTokensArr = m_Parser.GetTokens();
37 TokensArrayF* pTokens = &pTokensArr->Item(0)->m_Children;
38
39 for (size_t i=0; i<pTokens->GetCount(); i++)
40 {
41 if (pTokens->Item(i)->m_TokenKind == tkSubroutine)
42 {
43 m_SubrSet.insert(pTokens->Item(i)->m_Name);
44 }
45 else if (pTokens->Item(i)->m_TokenKind == tkFunction)
46 {
47 m_FuncSet.insert(pTokens->Item(i)->m_Name);
48 }
49 else if (pTokens->Item(i)->m_TokenKind == tkModule && pTokens->Item(i)->m_Name.IsSameAs(_T("openmp")))
50 {
51 TokensArrayF* pOMPMod = &pTokens->Item(i)->m_Children;
52 for (size_t j=0; j<pOMPMod->GetCount(); j++)
53 {
54 if (pOMPMod->Item(j)->m_TokenKind == tkVariable)
55 m_OpenMPKeywords.Add(pOMPMod->Item(j)->m_DisplayName);
56 }
57 }
58 else if (pTokens->Item(i)->m_TokenKind == tkModule && pTokens->Item(i)->m_Name.IsSameAs(_T("openacc")))
59 {
60 TokensArrayF* pACCMod = &pTokens->Item(i)->m_Children;
61 for (size_t j=0; j<pACCMod->GetCount(); j++)
62 {
63 if (pACCMod->Item(j)->m_TokenKind == tkVariable)
64 m_OpenACCKeywords.Add(pACCMod->Item(j)->m_DisplayName);
65 }
66 }
67 }
68 MakeOtherKeywordSet();
69 m_IsDone = true;
70 }
71
~KeywordsParserF()72 KeywordsParserF::~KeywordsParserF()
73 {
74 //dtor
75 }
76
HasTokenSuitableKind(const wxString & name,int tokKind)77 bool KeywordsParserF::HasTokenSuitableKind(const wxString& name, int tokKind)
78 {
79 if (!m_IsDone)
80 return true;
81
82 wxString nameLow = name.Lower();
83 bool found = false;
84 if ( (m_FuncSet.count(nameLow) && (tokKind & tkFunction)) ||
85 (m_SubrSet.count(nameLow) && (tokKind & tkSubroutine)) ||
86 (m_OtherKeywordSet.count(nameLow) && (tokKind & tkOther)) )
87 found = true;
88
89 return found;
90 }
91
GetCallTips(const wxString & name,wxArrayString & callTips,TokensArrayFlat * result)92 void KeywordsParserF::GetCallTips(const wxString& name, wxArrayString& callTips, TokensArrayFlat* result)
93 {
94 int tokKind = tkFunction | tkSubroutine;
95 size_t resCountOld = result->GetCount();
96 size_t resCount = m_Parser.FindMatchTokensDeclared(name, *result, tokKind, false);
97 for (size_t i=resCountOld; i<resCount; ++i)
98 {
99 callTips.Add(result->Item(i)->m_Args);
100 }
101 }
102
FindTokens(const wxString & name,TokensArrayFlat & result)103 void KeywordsParserF::FindTokens(const wxString& name, TokensArrayFlat& result)
104 {
105 int tokKind = tkFunction | tkSubroutine;
106 m_Parser.FindMatchTokensDeclared(name, result, tokKind, false);
107 }
108
MakeOtherKeywordSet()109 void KeywordsParserF::MakeOtherKeywordSet()
110 {
111 TokensArrayFlatClass tokensTmp;
112 TokensArrayFlat* result = tokensTmp.GetTokens();
113 size_t resCount = m_Parser.FindMatchTokensDeclared(_T("list_of_other_fortran_keywords"), *result, tkFunction, false);
114 if (resCount != 1)
115 {
116 Manager::Get()->GetLogManager()->Log(_T("FortranProject plugin error: "));
117 Manager::Get()->GetLogManager()->Log(_T("Can't parse 'list_of_other_fortran_keywords' function."));
118 return;
119 }
120 TokenFlat* token = result->Item(0);
121 wxString txtRange;
122 if (!m_Parser.FindTokenRange(*token, txtRange))
123 {
124 Manager::Get()->GetLogManager()->Log(_T("FortranProject plugin error: "));
125 Manager::Get()->GetLogManager()->Log(_T("Can't parse 'list_of_other_fortran_keywords' function."));
126 return;
127 }
128
129 //Parse
130 TokensArrayClass tokensKeyTmp;
131 TokensArrayF* parsResult = tokensKeyTmp.GetTokens();
132 ParserThreadF thread = ParserThreadF(wxEmptyString, txtRange, parsResult, fsfFree, true);
133 thread.ParseDeclarations();
134
135 for (size_t i=0; i<parsResult->GetCount(); i++)
136 {
137 if (parsResult->Item(i)->m_TokenKind == tkVariable)
138 {
139 m_OtherKeywordSet.insert(parsResult->Item(i)->m_Name);
140 }
141 }
142 }
143
GetKeywords(CompilerDirective cdir)144 const wxArrayString* KeywordsParserF::GetKeywords(CompilerDirective cdir)
145 {
146 if (cdir == cdOpenMP)
147 return &m_OpenMPKeywords;
148 else if (cdir == cdOpenACC)
149 return &m_OpenACCKeywords;
150 return NULL;
151 }
152