📄 parser.cpp
字号:
// display cache progress?
if (ConfigManager::Get()->Read(_T("/code_completion/show_cache_progress"), 1L))
{
progress = new wxProgressDialog(_("Code-completion plugin"),
_("Please wait while saving code-completion cache..."),
tcount + fcount);
}
// write cache magic
f->Write(CACHE_MAGIC, sizeof(CACHE_MAGIC));
SaveIntToFile(f, fcount); // num parsed files
SaveIntToFile(f, tcount); // num tokens
// m_ParsedFiles
for (unsigned int i = 0; i < fcount; ++i)
{
SaveStringToFile(f, m_ParsedFiles[i]);
if (progress)
progress->Update(++counter);
}
// m_Tokens
for (unsigned int i = 0; i < tcount; ++i)
{
// update m_Int for inheritance to be serialized properly
Token* token = m_Tokens[i];
token->m_Int = i;
}
for (unsigned int i = 0; i < tcount; ++i)
{
Token* token = m_Tokens[i];
token->SerializeOut(f);
if (progress)
progress->Update(++counter);
}
if (progress)
delete progress;
return true;
}
unsigned int Parser::GetFilesCount()
{
wxMutexLocker lock(s_mutexListProtection);
return m_ParsedFiles.GetCount();
}
bool Parser::Done()
{
wxMutexLocker lock(s_mutexListProtection);
return m_Pool.Done();
}
#ifndef STANDALONE
void Parser::SetTokenKindImage(int kind, const wxBitmap& bitmap, const wxBitmap& mask)
{
if (kind < PARSER_IMG_MIN || kind > PARSER_IMG_MAX)
return;
#ifdef __WXMSW__
m_pImageList->Replace(kind, bitmap, mask);
#endif
}
void Parser::SetTokenKindImage(int kind, const wxBitmap& bitmap, const wxColour& maskColor)
{
if (kind < PARSER_IMG_MIN || kind > PARSER_IMG_MAX)
return;
m_pImageList->Replace(kind, bitmap);//, maskColor);
}
void Parser::SetTokenKindImage(int kind, const wxIcon& icon)
{
if (kind < PARSER_IMG_MIN || kind > PARSER_IMG_MAX)
return;
m_pImageList->Replace(kind, icon);
}
int Parser::GetTokenKindImage(Token* token)
{
if (!token)
return PARSER_IMG_NONE;
switch (token->m_TokenKind)
{
case tkPreprocessor: return PARSER_IMG_PREPROCESSOR;
case tkEnum: return PARSER_IMG_ENUM;
case tkEnumerator: return PARSER_IMG_ENUMERATOR;
case tkClass: return PARSER_IMG_CLASS;
case tkNamespace: return PARSER_IMG_NAMESPACE;
case tkConstructor:
switch (token->m_Scope)
{
case tsProtected: return PARSER_IMG_CTOR_PROTECTED;
case tsPrivate: return PARSER_IMG_CTOR_PRIVATE;
default: return PARSER_IMG_CTOR_PUBLIC;
}
case tkDestructor:
switch (token->m_Scope)
{
case tsProtected: return PARSER_IMG_DTOR_PROTECTED;
case tsPrivate: return PARSER_IMG_DTOR_PRIVATE;
default: return PARSER_IMG_DTOR_PUBLIC;
}
case tkFunction:
switch (token->m_Scope)
{
case tsProtected: return PARSER_IMG_FUNC_PROTECTED;
case tsPrivate: return PARSER_IMG_FUNC_PRIVATE;
default: return PARSER_IMG_FUNC_PUBLIC;
}
case tkVariable:
switch (token->m_Scope)
{
case tsProtected: return PARSER_IMG_VAR_PROTECTED;
case tsPrivate: return PARSER_IMG_VAR_PRIVATE;
default: return PARSER_IMG_VAR_PUBLIC;
}
default: return PARSER_IMG_NONE;
}
}
#endif // STANDALONE
Token* Parser::FindTokenByName(const wxString& name, bool globalsOnly, short int kindMask)
{
// for (unsigned int i = m_Tokens.GetCount() - 1; i >= 0; --i)
Token* res = 0;
for (unsigned int i = 0; i < m_Tokens.GetCount(); ++i)
{
Token* token = m_Tokens[i];
if (globalsOnly && token->m_pParent)
continue;
if ((token->m_TokenKind & kindMask) && token->m_Name.Matches(name))
{
res = token;
// Manager::Get()->GetMessageManager()->DebugLog("token=%s (%d)", name.c_str(), token->m_Children.GetCount());
// return token;
}
}
// return 0;
return res;
}
Token* Parser::FindChildTokenByName(Token* parent, const wxString& name, bool useInheritance, short int kindMask)
{
if (!parent)
return FindTokenByName(name, false, kindMask);
for (unsigned int i = 0; i < parent->m_Children.GetCount(); ++i)
{
Token* token = parent->m_Children[i];
if ((token->m_TokenKind & kindMask) && token->m_Name.Matches(name))
return token;
}
// not found; check ancestors now...
if (useInheritance)
{
for (unsigned int i = 0; i < parent->m_Ancestors.GetCount(); ++i)
{
Token* inherited = FindChildTokenByName(parent->m_Ancestors[i], name, true, kindMask);
if (inherited)
return inherited;
}
}
return 0L;
}
Token* Parser::FindTokenByDisplayName(const wxString& name)
{
for (unsigned int i = 0; i < m_Tokens.GetCount(); ++i)
{
Token* token = m_Tokens[i];
if (token->m_DisplayName.Matches(name))
return token;
}
return 0L;
}
int TokensSortProc(Token** first, Token** second)
{
Token* parent1 = first[0]->m_pParent;
Token* parent2 = second[0]->m_pParent;
int diff = 0;
if (first[0]->m_IsTemporary != second[0]->m_IsTemporary)
{
// local block token, always first in list
return first[0]->m_IsTemporary ? -1 : 1;
}
else if (first[0]->m_IsLocal != second[0]->m_IsLocal)
{
// project tokens first, then global
return first[0]->m_IsLocal ? -1 : 1;
}
else if (parent1 && !parent2)
{
// first tokens that have a parent
return -1;
}
else if (!parent1 && parent2)
{
// first tokens that have a parent
return 1;
}
else if (parent1 && parent2)
{
if (parent1 != parent2)
{
// if both tokens have parent, order by *parent* name
diff = parent1->m_Name.CompareTo(parent2->m_Name);
if (diff)
return diff;
}
}
// order by token kind
int ret = first[0]->m_TokenKind - second[0]->m_TokenKind;
// finally order by token name, if all else fails...
if (!ret)
ret = first[0]->m_Name.CompareTo(second[0]->m_Name);
return ret;
}
void Parser::SortAllTokens()
{
m_Tokens.Sort(TokensSortProc);
}
void Parser::LinkInheritance(bool tempsOnly)
{
//Manager::Get()->GetMessageManager()->DebugLog("Linking inheritance...");
for (unsigned int i = 0; i < m_Tokens.GetCount(); ++i)
{
Token* token = m_Tokens[i];
if (token->m_TokenKind != tkClass)
continue;
if (tempsOnly && !token->m_IsTemporary)
continue;
if (token->m_AncestorsString.IsEmpty())
continue;
// only local symbols might change inheritance
if (token->m_IsLocal)
{
//Manager::Get()->GetMessageManager()->DebugLog("Removing ancestors from %s", token->m_Name.c_str());
token->m_Ancestors.Clear();
}
else
continue;
//Manager::Get()->GetMessageManager()->DebugLog("Token %s, Ancestors %s", token->m_Name.c_str(), token->m_AncestorsString.c_str());
wxStringTokenizer tkz(token->m_AncestorsString, _T(","));
while (tkz.HasMoreTokens())
{
wxString ancestor = tkz.GetNextToken();
if (ancestor.IsEmpty() || ancestor == token->m_Name)
continue;
//Manager::Get()->GetMessageManager()->DebugLog("Ancestor %s", ancestor.c_str());
Token* ancestorToken = FindTokenByName(ancestor, tkClass);
//Manager::Get()->GetMessageManager()->DebugLog(ancestorToken ? "Found" : "not Found");
if (ancestorToken)
{
//Manager::Get()->GetMessageManager()->DebugLog("Adding ancestor %s to %s", ancestorToken->m_Name.c_str(), token->m_Name.c_str());
token->m_Ancestors.Add(ancestorToken);
}
}
if (!token->m_IsLocal) // global symbols are linked once
{
//Manager::Get()->GetMessageManager()->DebugLog("Removing ancestor string from %s", token->m_Name.c_str(), token->m_Name.c_str());
token->m_AncestorsString.Clear();
}
}
}
bool Parser::ParseBuffer(const wxString& buffer, bool isLocal, bool bufferSkipBlocks)
{
ParserThreadOptions opts;
opts.wantPreprocessor = m_Options.wantPreprocessor;
opts.useBuffer = true;
opts.bufferSkipBlocks = bufferSkipBlocks;
return Parse(buffer, isLocal, opts);
}
void Parser::BatchParse(const wxArrayString& filenames)
{
m_Pool.BatchBegin();
for (unsigned int i = 0; i < filenames.GetCount(); ++i)
Parse(filenames[i]);
m_Pool.BatchEnd();
}
bool Parser::Parse(const wxString& filename, bool isLocal)
{
ParserThreadOptions opts;
opts.wantPreprocessor = m_Options.wantPreprocessor;
opts.useBuffer = false;
opts.bufferSkipBlocks = false;
return Parse(UnixFilename(filename), isLocal, opts);
}
bool Parser::Parse(const wxString& bufferOrFilename, bool isLocal, ParserThreadOptions& opts)
{
wxString buffOrFile = bufferOrFilename;
wxMutexLocker* lock = new wxMutexLocker(s_mutexListProtection);
bool parsed = !opts.useBuffer && m_ParsedFiles.Index(buffOrFile) != wxNOT_FOUND;
delete lock;
if (parsed)
{
#ifndef STANDALONE
// Manager::Get()->GetMessageManager()->DebugLog("%s is already parsed", buffOrFile.c_str());
#endif
return false; // already parsed
}
ParserThread* thread = new ParserThread(this,&this->m_abort_flag,
buffOrFile,
isLocal,
opts,
&m_Tokens);
if (!opts.useBuffer)
{
// lock = new wxMutexLocker(s_mutexListProtection);
m_ParsedFiles.Add(buffOrFile);
// LOGSTREAM << "Adding task for: " << buffOrFile << '\n';
m_Pool.AddTask(thread, true);
// delete lock;
return true;
}
else
{
bool ret = thread->Parse();
LinkInheritance(true);
delete thread;
return ret;
}
}
bool Parser::ParseBufferForFunctions(const wxString& buffer)
{
ParserThreadOptions opts;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -