Exemplo n.º 1
0
void CCTestFrame::OnMenuTokenSelected(wxCommandEvent& /*event*/)
{
    ParserBase* pb = CCTest::Get()->GetParser();
    TokenTree*  tt = CCTest::Get()->GetTokenTree();
    if (!pb || !tt) return;

    wxTextEntryDialog dlg(this, _T("Enter name of token to debug:"), _T("CCTest"));
    if (dlg.ShowModal()==wxID_OK)
    {
        wxString target = dlg.GetValue().Trim(true).Trim(false);
        if (target.IsEmpty()) return;

        // Search over all tokens, no AI whatsoever available
        bool found = false;
        for (size_t i=0; i<tt->size(); ++i)
        {
            Token* t = tt->at(i);
            if (t && t->m_Name.Matches(target))
            {
                CCDebugInfo di(this, pb, t); di.ShowModal();
                found = true;
                break; // found, exit for-loop
            }
        }
        if (!found)
            wxMessageBox(_("Token not found."), _("CCTest"),
                         wxOK | wxICON_INFORMATION, this);
    }
}
int MarkFileAsLocalThreadedTask::Execute()
{
    TRACE(_T("MarkFileAsLocalThreadedTask::Execute()"));
    if (!m_Project) return 0;
    if (!m_Parser)  return 0;

    // mark all project files as local
    for (FilesList::const_iterator it  = m_Project->GetFilesList().begin();
                                   it != m_Project->GetFilesList().end(); ++it)
    {
        ProjectFile* pf = *it;
        if (!pf)
            continue;

        if (ParserCommon::FileType(pf->relativeFilename) != ParserCommon::ftOther)
        {
            TokenTree* tree = m_Parser->GetTokenTree();

            CC_LOCKER_TRACK_TT_MTX_LOCK(s_TokenTreeMutex)

            tree->MarkFileTokensAsLocal(pf->file.GetFullPath(), true, m_Project);

            CC_LOCKER_TRACK_TT_MTX_UNLOCK(s_TokenTreeMutex)
        }
    }
Exemplo n.º 3
0
void CCDebugInfo::FillDescendants()
{
    TokenTree* tree = m_Parser->GetTokenTree();
    if (!tree) return;

    cmbDescendants->Clear();

    for (TokenIdxSet::const_iterator it = m_Token->m_Descendants.begin(); it != m_Token->m_Descendants.end(); ++it)
    {
        const Token* descendant = tree->at(*it);
        const wxString msgInvalidToken = _("<invalid token>");
        cmbDescendants->Append(wxString::Format(_T("%s (%d)"), descendant ? descendant->m_Name.wx_str() : msgInvalidToken.wx_str(), *it));
    }
    cmbDescendants->SetSelection(0);
}
void ClassBrowserBuilderThread::Init(NativeParser*         np,
                                     CCTreeCtrl*           treeTop,
                                     CCTreeCtrl*           treeBottom,
                                     const wxString&       active_filename,
                                     void*                 user_data, // active project
                                     const BrowserOptions& bo,
                                     TokenTree*            tt,
                                     int                   idThreadEvent)
{
    TRACE(_T("ClassBrowserBuilderThread::Init"));

    CC_LOCKER_TRACK_CBBT_MTX_LOCK(m_ClassBrowserBuilderThreadMutex);

    m_NativeParser     = np;
    m_CCTreeCtrlTop    = treeTop;
    m_CCTreeCtrlBottom = treeBottom;
    m_ActiveFilename   = active_filename;
    m_UserData         = user_data;
    m_BrowserOptions   = bo;
    m_TokenTree        = tt;
    m_idThreadEvent    = idThreadEvent;

    m_CurrentFileSet.clear();
    m_CurrentTokenSet.clear();

    TokenTree* tree = m_NativeParser->GetParser().GetTokenTree();

    // fill filter set for current-file-filter
    if (   m_BrowserOptions.displayFilter == bdfFile
        && !m_ActiveFilename.IsEmpty() )
    {
        // m_ActiveFilename is the full filename up to the extension dot. No extension though.
        // get all filenames' indices matching our mask
        wxArrayString paths = m_NativeParser->GetAllPathsByFilename(m_ActiveFilename);

        // Should add locker after called m_NativeParser->GetAllPathsByFilename
        CC_LOCKER_TRACK_TT_MTX_LOCK(s_TokenTreeMutex)

        TokenFileSet result;
        for (size_t i = 0; i < paths.GetCount(); ++i)
        {
            tree->GetFileMatches(paths[i], result, true, true);
            for (TokenFileSet::const_iterator tfs_it = result.begin(); tfs_it != result.end(); ++tfs_it)
                m_CurrentFileSet.insert(*tfs_it);
        }

        CC_LOCKER_TRACK_TT_MTX_UNLOCK(s_TokenTreeMutex)
    }
Exemplo n.º 5
0
void CCDebugInfo::OnFindClick(cb_unused wxCommandEvent& event)
{
    TokenTree* tree = m_Parser->GetTokenTree();
    if (!tree) return;

    wxString search = txtFilter->GetValue();

    m_Token = 0;

    // first determine if the user entered an ID or a search mask
    long unsigned id;
    if (search.ToULong(&id, 10))
    {
        // easy; ID
        m_Token = tree->at(id);
    }
    else
    {
        // find all matching tokens
        TokenIdxSet result;
        for (size_t i = 0; i < tree->size(); ++i)
        {
            const Token* token = tree->at(i);
            if (token && token->m_Name.Matches(search))
                result.insert(i);
        }

        // a single result?
        if (result.size() == 1)
            m_Token = tree->at(*(result.begin()));
        else
        {
            // fill a list and ask the user which token to display
            wxArrayString arr;
            wxArrayInt intarr;
            for (TokenIdxSet::const_iterator it = result.begin(); it != result.end(); ++it)
            {
                const Token* token = tree->at(*it);
                arr.Add(token->DisplayName());
                intarr.Add(*it);
            }
            int sel = wxGetSingleChoiceIndex(_("Please make a selection:"), _("Multiple matches"), arr, this);
            if (sel == -1)
                return;

            m_Token = tree->at(intarr[sel]);
        }
    }

    DisplayTokenInfo();
}
Exemplo n.º 6
0
void CCTestFrame::Start()
{
    if (m_ParserCtrl) m_ParserCtrl->SetSelection(1); // make sure "Output" tab is selected

    CCTestAppGlobal::s_includeDirs.Clear();
    CCTestAppGlobal::s_fileQueue.Clear();
    CCTestAppGlobal::s_filesParsed.Clear();

    // Obtain all include directories
    wxStringTokenizer tkz_inc(m_IncludeCtrl->GetValue(), _T("\r\n"));
    while ( tkz_inc.HasMoreTokens() )
    {
        wxString include = tkz_inc.GetNextToken().Trim(true).Trim(false);
        if (!include.IsEmpty())
            CCTestAppGlobal::s_includeDirs.Add(include);
    }

    if (m_DoHeadersCtrl->IsChecked())
    {
        // Obtain all priority header files
        wxStringTokenizer tkz_hdr(m_HeadersCtrl->GetValue(), _T(","));
        while (tkz_hdr.HasMoreTokens())
        {
            wxString header = tkz_hdr.GetNextToken().Trim(false).Trim(true);

            // Remove <> (if any)
            int lt = header.Find(wxT('<')); int gt = header.Find(wxT('>'),true);
            if (lt!=wxNOT_FOUND && gt!=wxNOT_FOUND && gt>lt)
                header = header.AfterFirst(wxT('<')).BeforeLast(wxT('>'));
            // Remove "" (if any)
            int oq = header.Find(wxT('"')); int cq = header.Find(wxT('"'),true);
            if (oq!=wxNOT_FOUND && cq!=wxNOT_FOUND && cq>oq)
                header = header.AfterFirst(wxT('"')).BeforeLast(wxT('"'));

            header = header.Trim(false).Trim(true);

            // Find the header files in include path's as provided
            // (practically the same as ParserBase::FindFileInIncludeDirs())
            for (size_t i=0; i<CCTestAppGlobal::s_includeDirs.GetCount(); ++i)
            {
                // Normalize the path (as in C::B's "NormalizePath()")
                wxFileName f_header(header);
                wxString   base_path(CCTestAppGlobal::s_includeDirs[i]);
                if (f_header.Normalize(wxPATH_NORM_ALL & ~wxPATH_NORM_CASE, base_path))
                {
                    wxString this_header = f_header.GetFullPath();
                    if ( ::wxFileExists(this_header) )
                        CCTestAppGlobal::s_fileQueue.Add(this_header);
                }
            }
        }
    }

    if (CCTestAppGlobal::s_fileQueue.IsEmpty() && !m_Control->GetLength())
    {
        wxMessageBox(wxT("Main file not found and buffer empty. Nothing to do."),
                     _("Information"), wxOK | wxICON_INFORMATION, this);
        return;
    }

    if (m_DoHideCtrl && m_DoHideCtrl->IsChecked()) Hide();

    m_ProgDlg = new wxProgressDialog(_T("Please wait, operating..."), _("Preparing...\nPlease wait..."), 0, this, wxPD_APP_MODAL);
    m_ProgDlg->SetSize(640,100);
    m_ProgDlg->Layout();
    m_ProgDlg->CenterOnParent();

    m_LogCount = 0;
    m_LogCtrl->Clear();
    CCTest::Get()->Clear(); // initial clearance

    // make sure not to over-write an existing file (in case content had changed)
    wxString tf(wxFileName::CreateTempFileName(wxT("cc")));
    // make the parser recognise it as header file:
    wxFileName fn(tf); fn.SetExt(wxT("h")); wxRemoveFile(tf); // no longer needed
    if (m_Control->SaveFile(fn.GetFullPath()))
        CCTestAppGlobal::s_fileQueue.Add(fn.GetFullPath());
    else
        AppendToLog(_T("Unable to parse buffer (could not convert to file)."));

    AppendToLog(_T("--------------M-a-i-n--L-o-g--------------\r\n\r\n"));

    // parse file from the queue one-by-one
    while (!CCTestAppGlobal::s_fileQueue.IsEmpty())
    {
        wxString file = CCTestAppGlobal::s_fileQueue.Item(0);
        CCTestAppGlobal::s_fileQueue.Remove(file);
        if (file.IsEmpty()) continue;

        AppendToLog(_T("-----------I-n-t-e-r-i-m--L-o-g-----------"));
        m_CurrentFile = file;

        m_ProgDlg->Update(-1, m_CurrentFile);
        m_StatuBar->SetStatusText(m_CurrentFile);

        // This is the core parse stage for files
        CCTest::Get()->Start(m_CurrentFile);
        CCTestAppGlobal::s_filesParsed.Add(m_CurrentFile); // done
    }
    // don't forget to remove the temporary file (w/ ".h" extension)
    wxRemoveFile(fn.GetFullPath());

    m_ProgDlg->Update(-1, wxT("Creating tree log..."));
    AppendToLog(_T("--------------T-r-e-e--L-o-g--------------\r\n"));
    CCTest::Get()->PrintTree();

    m_ProgDlg->Update(-1, wxT("Creating list log..."));
    AppendToLog(_T("--------------L-i-s-t--L-o-g--------------\r\n"));
    CCTest::Get()->PrintList();

    if (m_DoTreeCtrl->IsChecked())
    {
        m_ProgDlg->Update(-1, wxT("Serializing tree..."));

        Freeze();
        m_TreeCtrl->SetValue( CCTest::Get()->SerializeTree() );
        Thaw();
    }

    // Here we are going to test the expression solving algorithm

    NativeParserTest nativeParserTest;

    wxString exp = _T("obj.m_Member1");

    TokenIdxSet searchScope;
    searchScope.insert(-1);

    TokenIdxSet result;

    TokenTree *tree = CCTest::Get()->GetTokenTree();

    nativeParserTest.TestExpression(exp,
                                    tree,
                                    searchScope,
                                    result );

    wxLogMessage(_T("Result have %lu matches"), static_cast<unsigned long>(result.size()));


    for (TokenIdxSet::iterator it=result.begin(); it!=result.end(); ++it)
    {
        Token* token = tree->at(*it);
        if (token)
        {
            wxString log;
            log << token->GetTokenKindString() << _T(" ")
                << token->DisplayName()        << _T("\t[")
                << token->m_Line               << _T(",")
                << token->m_ImplLine           << _T("]");
            CCLogger::Get()->Log(log);
        }
    }


    if (m_ProgDlg) { delete m_ProgDlg; m_ProgDlg = 0; }

    if ( !IsShown() ) Show();

    TokenTree* tt = CCTest::Get()->GetTokenTree();
    if (tt)
    {
        AppendToLog((wxString::Format(_("The parser contains %lu tokens, found in %lu files."),
                                      static_cast<unsigned long>(tt->size()), static_cast<unsigned long>(tt->m_FileMap.size()))));
    }
}
Exemplo n.º 7
0
size_t CodeRefactoring::VerifyResult(const TokenIdxSet& targetResult, const wxString& targetText,
                                     bool isLocalVariable)
{
    EditorManager* edMan = Manager::Get()->GetEditorManager();
    cbEditor* editor = edMan->GetBuiltinActiveEditor();
    if (!editor)
        return 0;

    const Token* parentOfLocalVariable = nullptr;
    if (isLocalVariable)
    {
        TokenTree* tree = m_NativeParser.GetParser().GetTokenTree();

        CC_LOCKER_TRACK_TT_MTX_LOCK(s_TokenTreeMutex)

        const Token* token = tree->at(*targetResult.begin());
        parentOfLocalVariable = tree->at(token->m_ParentIndex);

        CC_LOCKER_TRACK_TT_MTX_UNLOCK(s_TokenTreeMutex)
    }

    // now that list is filled, we'll search
    cbStyledTextCtrl* control = new cbStyledTextCtrl(editor->GetParent(), wxID_ANY, wxDefaultPosition,
                                                     wxSize(0, 0));
    control->Show(false);

    // styled the text to support control->GetStyleAt()
    cbEditor::ApplyStyles(control);
    EditorColourSet edColSet;

    size_t totalCount = 0;
    for (SearchDataMap::const_iterator it = m_SearchDataMap.begin(); it != m_SearchDataMap.end(); ++it)
        totalCount += it->second.size();

    // let's create a progress dialog because it might take some time depending on the files count
    wxProgressDialog* progress = new wxProgressDialog(_("Code Refactoring"),
                                                      _("Please wait while verifying result..."),
                                                      totalCount,
                                                      Manager::Get()->GetAppWindow(),
                                                      wxPD_AUTO_HIDE | wxPD_APP_MODAL | wxPD_CAN_ABORT);
    PlaceWindow(progress);

    size_t task = totalCount;
    TokenIdxSet result;
    bool userBreak = false;
    for (SearchDataMap::iterator it = m_SearchDataMap.begin(); it != m_SearchDataMap.end();)
    {
        // check if the file is already opened in built-in editor and do search in it
        cbEditor* ed = edMan->IsBuiltinOpen(it->first);
        if (ed)
            control->SetText(ed->GetControl()->GetText());
        else // else load the file in the control
        {
            EncodingDetector detector(it->first);
            if (!detector.IsOK())
            {
                task -= it->second.size();
                m_SearchDataMap.erase(it++);
                continue; // failed
            }
            control->SetText(detector.GetWxStr());
        }

        // apply the corlor setting
        edColSet.Apply(editor->GetLanguage(), control);

        ccSearchData searchData = { control, it->first };
        for (SearchDataList::iterator itList = it->second.begin(); itList != it->second.end();)
        {
            // update the progress bar
            if (!progress->Update(totalCount - (--task)))
            {
                userBreak = true;
                break; // user pressed "Cancel"
            }

            // skip string or comment
            const int style = control->GetStyleAt(itList->pos);
            if (control->IsString(style) || control->IsComment(style))
            {
                it->second.erase(itList++);
                continue;
            }

            // do cc search
            const int endOfWord = itList->pos + targetText.Len();
            control->GotoPos(endOfWord);
            m_NativeParser.MarkItemsByAI(&searchData, result, true, false, true, endOfWord);
            if (result.empty())
            {
                it->second.erase(itList++);
                continue;
            }

            // verify result
            TokenIdxSet::const_iterator findIter = targetResult.begin();
            for (; findIter != targetResult.end(); ++findIter)
            {
                if (result.find(*findIter) != result.end())
                    break;
            }

            if (findIter == targetResult.end()) // not found
                it->second.erase(itList++);
            else
            {
                // handle for local variable
                if (isLocalVariable)
                {
                    bool do_continue = false;

                    TokenTree* tree = m_NativeParser.GetParser().GetTokenTree();

                    CC_LOCKER_TRACK_TT_MTX_LOCK(s_TokenTreeMutex)

                    const Token* token = tree->at(*findIter);
                    if (token)
                    {
                        const Token* parent = tree->at(token->m_ParentIndex);
                        if (parent != parentOfLocalVariable)
                        {
                            it->second.erase(itList++);
                            do_continue = true;
                        }
                    }

                    CC_LOCKER_TRACK_TT_MTX_UNLOCK(s_TokenTreeMutex)

                    if (do_continue) continue;
                }

                ++itList;
            }
        }

        if (it->second.empty())
            m_SearchDataMap.erase(it++);
        else
            ++it;

        if (userBreak)
            break;
    }

    delete control; // done with it
    delete progress; // done here too

    return m_SearchDataMap.size();
}
Exemplo n.º 8
0
bool CodeRefactoring::Parse()
{
    cbEditor* editor = Manager::Get()->GetEditorManager()->GetBuiltinActiveEditor();
    if (!editor)
        return false;

    const wxString targetText = GetSymbolUnderCursor();
    if (targetText.IsEmpty())
        return false;

    TokenIdxSet targetResult;
    const int endOfWord = editor->GetControl()->WordEndPosition(editor->GetControl()->GetCurrentPos(), true);
    m_NativeParser.MarkItemsByAI(targetResult, true, false, true, endOfWord);
    if (targetResult.empty())
    {
        cbMessageBox(_("Symbol not found under cursor!"), _("Code Refactoring"), wxOK | wxICON_WARNING);
        return false;
    }

    // handle local variables
    bool isLocalVariable = false;

    TokenTree* tree = m_NativeParser.GetParser().GetTokenTree();

    CC_LOCKER_TRACK_TT_MTX_LOCK(s_TokenTreeMutex)

    const Token* token = tree->at(*targetResult.begin());
    if (token)
    {
        const Token* parent = tree->at(token->m_ParentIndex);
        if (parent && parent->m_TokenKind == tkFunction)
            isLocalVariable = true;
    }

    CC_LOCKER_TRACK_TT_MTX_UNLOCK(s_TokenTreeMutex)

    wxArrayString files;
    cbProject* project = m_NativeParser.GetProjectByEditor(editor);
    if (isLocalVariable || !project)
        files.Add(editor->GetFilename());
    else
    {
        ScopeDialog scopeDlg(Manager::Get()->GetAppWindow(), _("Code Refactoring"));
        const int ret = scopeDlg.ShowModal();
        if (ret == ScopeDialog::ID_OPEN_FILES)
            GetOpenedFiles(files);
        else if (ret == ScopeDialog::ID_PROJECT_FILES)
            GetAllProjectFiles(files, project);
        else
            return false;
    }

    if (files.IsEmpty())
        return false;

    size_t count = SearchInFiles(files, targetText);
    if (count)
        count = VerifyResult(targetResult, targetText, isLocalVariable);

    return count != 0;
}
Exemplo n.º 9
0
void CCDebugInfo::OnSave(cb_unused wxCommandEvent& event)
{
    TokenTree* tree = m_Parser->GetTokenTree();

    wxArrayString saveWhat;
    saveWhat.Add(_("Dump the tokens tree"));
    saveWhat.Add(_("Dump the serialised tokens tree"));
    saveWhat.Add(_("Dump the file list"));
    saveWhat.Add(_("Dump the list of include directories"));
    saveWhat.Add(_("Dump the token list of files"));

    int sel = wxGetSingleChoiceIndex(_("What do you want to save?"),
                                     _("CC Debug Info"), saveWhat, this);

    switch (sel)
    {
        case -1:
            // cancelled
            return;

        case 0:
            {
                wxString tt;
                { // life time of wxWindowDisabler/wxBusyInfo
                    wxWindowDisabler disableAll;
                    wxBusyInfo running(_("Obtaining tokens tree... please wait (this may take several seconds)..."),
                                       Manager::Get()->GetAppWindow());

                    tt = tree->m_Tree.dump();
                }
                CCDebugInfoHelper::SaveCCDebugInfo(_("Save tokens tree"), tt);
            }
            break;
        case 1:
            {
                wxString tt_ser;
                { // life time of wxWindowDisabler/wxBusyInfo
                    wxWindowDisabler disableAll;
                    wxBusyInfo running(_("Serialising tokens tree... please wait (this may take several seconds)..."),
                                       Manager::Get()->GetAppWindow());

                    tt_ser = tree->m_Tree.Serialize();
                }
                CCDebugInfoHelper::SaveCCDebugInfo(_("Save serialised tokens tree"), tt_ser);
            }
            break;
        case 2:
            {
                wxString files;
                for (size_t i = 0; i < tree->m_FilenameMap.size(); ++i)
                {
                    wxString file = tree->m_FilenameMap.GetString(i);
                    if (!file.IsEmpty())
                        files += file + _T("\r\n");
                }

                CCDebugInfoHelper::SaveCCDebugInfo(_("Save file list"), files);
            }
            break;
        case 3:
            {
                wxString dirs;
                const wxArrayString& dirsArray = m_Parser->GetIncludeDirs();
                for (size_t i = 0; i < dirsArray.GetCount(); ++i)
                {
                    const wxString& dir = dirsArray[i];
                    if (!dir.IsEmpty())
                        dirs += dir + _T("\r\n");
                }
                CCDebugInfoHelper::SaveCCDebugInfo(_("Save list of include directories"), dirs);
            }
            break;
        case 4:
            {
                wxString fileTokens;
                {
                    wxWindowDisabler disableAll;
                    wxBusyInfo running(_("Obtaining tokens tree... please wait (this may take several seconds)..."),
                                       Manager::Get()->GetAppWindow());
                    for (size_t i = 0; i < tree->m_FilenameMap.size(); ++i)
                    {
                        const wxString file = tree->m_FilenameMap.GetString(i);
                        if (!file.IsEmpty())
                        {
                            fileTokens += file + _T("\r\n");

                            TokenIdxSet result;
                            tree->FindTokensInFile(file, result, tkUndefined);
                            for (TokenIdxSet::const_iterator it = result.begin(); it != result.end(); ++it)
                            {
                                const Token* token = tree->at(*it);
                                fileTokens << token->GetTokenKindString() << _T(" ");
                                if (token->m_TokenKind == tkFunction)
                                    fileTokens << token->m_Name << token->GetFormattedArgs() << _T("\t");
                                else
                                    fileTokens << token->DisplayName() << _T("\t");
                                fileTokens << _T("[") << token->m_Line << _T(",") << token->m_ImplLine << _T("]");
                                fileTokens << _T("\r\n");
                            }
                        }
                        fileTokens += _T("\r\n");
                    }
                }

                CCDebugInfoHelper::SaveCCDebugInfo(_("Save token list of files"), fileTokens);
            }
            break;
        default:
            cbMessageBox(_("Invalid selection."), _("CC Debug Info"));
    }
}
Exemplo n.º 10
0
void CCDebugInfo::DisplayTokenInfo()
{
    if (!m_Token)
    {
        txtID->SetLabel(wxEmptyString);
        txtName->SetLabel(wxEmptyString);
        txtKind->SetLabel(wxEmptyString);
        txtScope->SetLabel(wxEmptyString);
        txtFullType->SetLabel(wxEmptyString);
        txtBaseType->SetLabel(wxEmptyString);
        txtArgs->SetLabel(wxEmptyString);
        txtArgsStripped->SetLabel(wxEmptyString);
        txtTemplateArg->SetLabel(wxEmptyString);
        txtIsOp->SetLabel(wxEmptyString);
        txtIsLocal->SetLabel(wxEmptyString);
        txtNamespace->SetLabel(wxEmptyString);
        txtParent->SetLabel(wxEmptyString);
        cmbChildren->Clear();
        cmbAncestors->Clear();
        cmbDescendants->Clear();
        txtDeclFile->SetLabel(wxEmptyString);
        txtImplFile->SetLabel(wxEmptyString);
        return;
    }

    TokenTree* tree = m_Parser->GetTokenTree();
    if (!tree) return;

    const Token* parent = tree->at(m_Token->m_ParentIndex);
    tree->RecalcInheritanceChain(m_Token);

    wxString args     = m_Token->GetFormattedArgs();
    wxString argsStr  = m_Token->m_BaseArgs;
    wxString tmplArg  = m_Token->m_TemplateArgument;
    wxString fullType = m_Token->m_FullType;

    // so they can be displayed in wxStaticText
    args.Replace(_T("&"), _T("&&"), true);
    argsStr.Replace(_T("&"), _T("&&"), true);
    tmplArg.Replace(_T("&"), _T("&&"), true);
    fullType.Replace(_T("&"), _T("&&"), true);

    txtID->SetLabel(wxString::Format(_T("%d"), m_Token->m_Index));
    txtName->SetLabel(m_Token->m_Name);
    txtKind->SetLabel(m_Token->GetTokenKindString());
    txtScope->SetLabel(m_Token->GetTokenScopeString());
    txtFullType->SetLabel(fullType);
    txtBaseType->SetLabel(m_Token->m_BaseType);
    txtArgs->SetLabel(args);
    txtArgsStripped->SetLabel(argsStr);
    txtTemplateArg->SetLabel(tmplArg);
    txtIsOp->SetLabel(m_Token->m_IsOperator ? _("Yes") : _("No"));
    txtIsLocal->SetLabel(m_Token->m_IsLocal ? _("Yes") : _("No"));
    txtIsTemp->SetLabel(m_Token->m_IsTemp ? _("Yes") : _("No"));
    txtIsConst->SetLabel(m_Token->m_IsConst ? _("Yes") : _("No"));
    txtIsNoExcept->SetLabel(m_Token->m_IsNoExcept ? _("Yes") : _("No"));
    txtNamespace->SetLabel(m_Token->GetNamespace());
    txtParent->SetLabel(wxString::Format(_T("%s (%d)"), parent ? parent->m_Name.c_str() : (const wxChar*)_("<Global namespace>"), m_Token->m_ParentIndex));

    FillChildren();
    FillAncestors();
    FillDescendants();

    if (!m_Token->GetFilename().IsEmpty())
        txtDeclFile->SetLabel(wxString::Format(_T("%s : %u"), m_Token->GetFilename().c_str(), m_Token->m_Line));
    else
        txtDeclFile->SetLabel(wxEmptyString);
    if (!m_Token->GetImplFilename().IsEmpty())
        txtImplFile->SetLabel(wxString::Format(_("%s : %u (code lines: %u to %u)"), m_Token->GetImplFilename().c_str(), m_Token->m_ImplLine, m_Token->m_ImplLineStart, m_Token->m_ImplLineEnd));
    else
        txtImplFile->SetLabel(wxEmptyString);
    txtUserData->SetLabel(wxString::Format(_T("0x%p"), m_Token->m_UserData));
}