📄 parser.cpp
字号:
opts.wantPreprocessor = m_Options.wantPreprocessor;
opts.useBuffer = false;
opts.bufferSkipBlocks = false;
ParserThread* thread = new ParserThread(this,&this->m_abort_flag,
wxEmptyString,
false,
opts,
&m_Tokens);
return thread->ParseBufferForFunctions(buffer);
}
bool Parser::RemoveFile(const wxString& filename)
{
wxMutexLocker lock(s_mutexListProtection);
wxMutexLocker lock1(s_mutexProtection);
wxString file = UnixFilename(filename);
if (m_ParsedFiles.Index(file) != wxNOT_FOUND)
{
// only if it has been parsed before...
// delete any entries that belong to the file in question
// FIXME: what happens with entries *linked* to this entry?
unsigned int i = 0;
while (i < m_Tokens.GetCount())
{
if (m_Tokens[i]->m_Filename.Matches(file))
m_Tokens.RemoveAt(i);
else
++i;
}
m_ParsedFiles.Remove(file);
}
else
return false;
return true;
}
bool Parser::Reparse(const wxString& filename, bool isLocal)
{
if (!Done())
return false; // if still parsing, exit with error
wxString file = UnixFilename(filename);
// Manager::Get()->GetMessageManager()->DebugLog(_("Reparsing %s"), file.c_str());
RemoveFile(file);
ClearTemporaries();
wxMutexLocker* lock = new wxMutexLocker(s_mutexListProtection);
m_ReparsedFiles.Add(file);
delete lock;
return Parse(file, isLocal);
}
void Parser::Clear()
{
// Manager::Get()->GetMessageManager()->DebugLog(_("Parser::Clear: Disconnecting events..."));
DisconnectEvents();
// Manager::Get()->GetMessageManager()->DebugLog(_("Parser::Clear: Terminating all threads..."));
TerminateAllThreads();
wxSafeYield();
wxSleep(0);
wxMutexLocker* lockl = new wxMutexLocker(s_mutexListProtection);
// Manager::Get()->GetMessageManager()->DebugLog(_("Parser::Clear: Clearing 'm_ParsedFiles'..."));
m_ParsedFiles.Clear();
// Manager::Get()->GetMessageManager()->DebugLog(_("Parser::Clear: Clearing 'm_ReparsedFiles'..."));
m_ReparsedFiles.Clear();
// Manager::Get()->GetMessageManager()->DebugLog(_("Parser::Clear: Clearing 'm_IncludeDirs'..."));
m_IncludeDirs.Clear();
delete lockl;
// Manager::Get()->GetMessageManager()->DebugLog(_("Parser::Clear: Locking s_mutexProtection and clearing m_Tokens..."));
wxMutexLocker lock(s_mutexProtection);
WX_CLEAR_ARRAY(m_Tokens);
m_Tokens.Clear();
// Manager::Get()->GetMessageManager()->DebugLog(_("Parser::Clear: wxSafeYield..."));
wxSafeYield();
// Manager::Get()->GetMessageManager()->DebugLog(_("Parser::Clear: Connecting Events..."));
ConnectEvents();
m_UsingCache = false;
m_CacheFilesCount = 0;
m_CacheTokensCount = 0;
m_abort_flag = false;
// Manager::Get()->GetMessageManager()->DebugLog(_("Parser::Clear: Done."));
}
void Parser::ClearTemporaries()
{
if (!Done())
return;
unsigned int i = 0;
while (i < m_Tokens.GetCount())
{
Token* token = m_Tokens[i];
if (token->m_IsTemporary)
m_Tokens.RemoveAt(i);
else
++i;
}
}
void Parser::TerminateAllThreads()
{
Manager::Get()->GetMessageManager()->DebugLog(_("Parser::TerminateAllThreads: Aborting all tasks..."));
m_Pool.AbortAllTasks();
}
void Parser::PauseAllThreads()
{
// wxLogNull ln; // no other logging
// wxMutexLocker lock(s_mutexListProtection);
// for (unsigned int i = 0; i < m_Threads.GetCount(); ++i)
// m_Threads[i]->Pause();
}
void Parser::ResumeAllThreads()
{
// wxLogNull ln; // no other logging
// wxMutexLocker lock(s_mutexListProtection);
// for (unsigned int i = 0; i < m_Threads.GetCount(); ++i)
// m_Threads[i]->Resume();
}
void Parser::OnStartThread(CodeBlocksEvent& event)
{
event.Skip();
}
void Parser::OnEndThread(CodeBlocksEvent& event)
{
event.Skip();
}
void Parser::OnAllThreadsDone(CodeBlocksEvent& event)
{
LinkInheritance(false);
wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED, PARSER_END);
evt.SetClientData(this);
wxPostEvent(m_pParent, evt);
}
void Parser::OnNewToken(wxCommandEvent& event)
{
#ifndef STANDALONE
Manager::Get()->GetMessageManager()->DebugLog(event.GetString());
#endif
}
void Parser::OnParseFile(wxCommandEvent& event)
{
// LOGSTREAM << "Parser::OnParseFile: " << event.GetString() << "\n";
// a ParserThread ran into an #include directive
// it's up to us to decide to parse this file...
if ((event.GetInt() == 0 && !m_Options.followLocalIncludes) ||
(event.GetInt() == 1 && !m_Options.followGlobalIncludes))
return;
// the string is thread's_filename+included_filename
wxString filename = event.GetString();
int idx = filename.First('+');
wxFileName fname;
wxFileName source;
wxString base;
if (idx == -1)
return;
fname.Assign(filename.Mid(idx + 1));
source.Assign(filename.Left(idx - 1));
if (event.GetInt() == 0)
base = source.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR);
else
{
// loop through all known include dirs
// and locate the file...
for (unsigned int i = 0; i < m_IncludeDirs.GetCount(); ++i)
{
base = m_IncludeDirs[i];
wxFileName tmp = fname;
tmp.Normalize(wxPATH_NORM_ALL & ~wxPATH_NORM_CASE, base);
if (wxFileExists(tmp.GetFullPath()))
break;
}
}
fname.Normalize(wxPATH_NORM_ALL & ~wxPATH_NORM_CASE, base);
filename = fname.GetFullPath();
/*wxMutexLocker* lock = new wxMutexLocker(s_mutexListProtection);
bool abort = m_ReparsedFiles.Index(filename) != wxNOT_FOUND;
delete lock;
if (abort)
return; // the file is being re-parsed; don't follow includes
*/
if (m_ParsedFiles.Index(filename) != wxNOT_FOUND) // parsed file
return;
// Manager::Get()->GetMessageManager()->DebugLog("Adding in parse queue: %s", filename.c_str());
bool res = false;
if (m_ReparsedFiles.Index(source.GetFullPath()) != wxNOT_FOUND) // reparsing file
res = Reparse(filename, event.GetInt() == 0);
else
res = Parse(filename, event.GetInt() == 0);
if (res)
{
#if 0
#ifndef STANDALONE
Manager::Get()->GetMessageManager()->DebugLog("Adding in parse queue: %s", filename.c_str());
#endif
#endif
}
}
void Parser::BuildTree(wxTreeCtrl& tree)
{
if (!Done())
return;
tree.Freeze();
tree.DeleteAllItems();
#ifndef STANDALONE
tree.SetImageList(m_pImageList);
#endif
m_RootNode = tree.AddRoot(_("Symbols"), PARSER_IMG_SYMBOLS_FOLDER);
if (m_BrowserOptions.viewFlat)
{
for (unsigned int x = 0; x < m_Tokens.GetCount(); ++x)
{
Token* token = m_Tokens[x];
if (!token->m_pParent && // base (no parent)
token->m_IsLocal) // local symbols only
AddTreeNode(tree, m_RootNode, token);
}
tree.Expand(m_RootNode);
tree.Thaw();
return;
}
wxTreeItemId globalNS = tree.AppendItem(m_RootNode, _("Global namespace"), PARSER_IMG_NAMESPACE);
AddTreeNamespace(tree, globalNS, 0L);
BuildTreeNamespace(tree, m_RootNode, 0L);
tree.Expand(m_RootNode);
tree.Thaw();
}
void Parser::BuildTreeNamespace(wxTreeCtrl& tree, const wxTreeItemId& parentNode, Token* parent)
{
for (unsigned int x = 0; x < m_Tokens.GetCount(); ++x)
{
Token* token = m_Tokens[x];
if (token->m_pParent == parent &&
token->m_IsLocal && // local symbols only
token->m_TokenKind == tkNamespace) // namespaces
{
ClassTreeData* ctd = new ClassTreeData(token);
wxTreeItemId newNS = tree.AppendItem(parentNode, token->m_Name, PARSER_IMG_NAMESPACE, -1, ctd);
BuildTreeNamespace(tree, newNS, token);
AddTreeNamespace(tree, newNS, token);
}
}
}
void Parser::AddTreeNamespace(wxTreeCtrl& tree, const wxTreeItemId& parentNode, Token* parent)
{
wxTreeItemId node = tree.AppendItem(parentNode, _("Classes"), PARSER_IMG_CLASS_FOLDER);
for (unsigned int x = 0; x < m_Tokens.GetCount(); ++x)
{
Token* token = m_Tokens[x];
if (token->m_pParent == parent && // parent matches
token->m_IsLocal && // local symbols only
token->m_TokenKind == tkClass) // classes
{
AddTreeNode(tree, node, token);
}
}
node = tree.AppendItem(parentNode, _("Enums"), PARSER_IMG_ENUMS_FOLDER);
for (unsigned int x = 0; x < m_Tokens.GetCount(); ++x)
{
Token* token = m_Tokens[x];
if (token->m_pParent == parent && // parent matches
token->m_IsLocal && // local symbols only
token->m_TokenKind == tkEnum) // enums
{
AddTreeNode(tree, node, token);
}
}
node = tree.AppendItem(parentNode, _("Preprocessor"), PARSER_IMG_PREPROC_FOLDER);
for (unsigned int x = 0; x < m_Tokens.GetCount(); ++x)
{
Token* token = m_Tokens[x];
if (token->m_pParent == parent && // parent matches
token->m_IsLocal && // local symbols only
token->m_TokenKind == tkPreprocessor) // preprocessor
{
AddTreeNode(tree, node, token);
}
}
node = tree.AppendItem(parentNode, _("Others"), PARSER_IMG_OTHERS_FOLDER);
for (unsigned int x = 0; x < m_Tokens.GetCount(); ++x)
{
Token* token = m_Tokens[x];
if (token->m_pParent == parent && // parent matches
token->m_IsLocal && // local symbols only
(token->m_TokenKind == tkEnumerator || // enumerators
token->m_TokenKind == tkFunction || // functions
token->m_TokenKind == tkVariable || // variables
token->m_TokenKind == tkUndefined)) // others
{
AddTreeNode(tree, node, token);
}
}
}
void Parser::AddTreeNode(wxTreeCtrl& tree, const wxTreeItemId& parentNode, Token* token, bool childrenOnly)
{
if (!token)
return;
ClassTreeData* ctd = new ClassTreeData(token);
int image = -1;
#ifndef STANDALONE
image = GetTokenKindImage(token);
#endif
wxString str = token->m_Name + token->m_Args;
if (!token->m_ActualType.IsEmpty())
str = str + _T(" : ") + token->m_ActualType;
wxTreeItemId node = childrenOnly ? parentNode : tree.AppendItem(parentNode, str, image, -1, ctd);
// add children
for (unsigned int i = 0; i < token->m_Children.GetCount(); ++i)
{
Token* childToken = token->m_Children[i];
AddTreeNode(tree, node, childToken);
}
if (!m_BrowserOptions.showInheritance || (token->m_TokenKind != tkClass && token->m_TokenKind != tkNamespace))
return;
// add ancestor's children
for (unsigned int x = 0; x < token->m_Ancestors.GetCount(); ++x)
{
Token* ancestor = token->m_Ancestors[x];
AddTreeNode(tree, node, ancestor, true);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -