⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 parser.cpp

📁 非常好用的可移植的多平台C/C++源代码编辑器
💻 CPP
📖 第 1 页 / 共 3 页
字号:
    // 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 + -