void RefactoringStorage::StoreTokens(const wxString& filename, const CppToken::List_t& tokens, bool startTx)
{
    if ( !IsCacheReady() ) {
        return;
    }

    if ( !m_db.IsOpen() )
        return;

    try {
        if ( startTx )  {
            Begin();
        }

        DoDeleteFile(filename);

        CppToken::List_t::const_iterator iter = tokens.begin();
        for(; iter != tokens.end(); ++iter ) {
            iter->store( &m_db );
        }

        DoUpdateFileTimestamp(filename);

        if ( startTx )  {
            Commit();
        }

    } catch (wxSQLite3Exception &e) {
        if ( startTx ) {
            Rollback();
        }
        wxUnusedVar(e);
    }
}
    void *Entry() {
        RefactoringStorage storage;
        storage.Open(m_workspaceFile);
        storage.m_cacheStatus = RefactoringStorage::CACHE_READY;

        wxCommandEvent evtStatus1(wxEVT_REFACTORING_ENGINE_CACHE_INITIALIZING);
        evtStatus1.SetInt(0);
        evtStatus1.SetString( m_workspaceFile );
        EventNotifier::Get()->AddPendingEvent( evtStatus1 );

        size_t count = 0;

        storage.Begin();
        wxFileList_t::const_iterator iter = m_files.begin();
        for(; iter != m_files.end(); ++iter ) {

            if ( TestDestroy() ) {
                // we requested to stop
                storage.Commit();
                wxCommandEvent evtStatus2(wxEVT_REFACTORING_ENGINE_CACHE_INITIALIZING);
                evtStatus2.SetInt(100);
                evtStatus2.SetString( m_workspaceFile );
                EventNotifier::Get()->AddPendingEvent( evtStatus2 );
                return NULL;
            }

            if ( !TagsManagerST::Get()->IsValidCtagsFile( (*iter) ) ) {
                continue;
            }

            ++count;
            if ( count % 100 == 0 ) {
                storage.Commit();
                storage.Begin();
            }

            wxString fullpath = iter->GetFullPath();
            if ( !storage.IsFileUpToDate(fullpath) ) {
                CppWordScanner scanner( fullpath );
                CppToken::List_t tokens = scanner.tokenize();

                if ( false ) {
                    CppToken::List_t::iterator tokIter = tokens.begin();
                    for(; tokIter != tokens.end(); ++tokIter ) {
                        wxPrintf("%s | %s | %d\n", tokIter->getFilename().c_str(), tokIter->getName().c_str(), (int)tokIter->getOffset());
                    }
                }

                storage.StoreTokens( fullpath, tokens, false );
            }
        }

        storage.Commit();
        wxCommandEvent evtStatus2(wxEVT_REFACTORING_ENGINE_CACHE_INITIALIZING);
        evtStatus2.SetInt(100);
        evtStatus2.SetString( m_workspaceFile );
        EventNotifier::Get()->AddPendingEvent( evtStatus2 );
        return NULL;
    }
Beispiel #3
0
void RefactoringEngine::RenameLocalSymbol(const wxString& symname, const wxFileName& fn, int line, int pos)
{
    // Clear previous results
    Clear();

    // Load the file and get a state map + the text from the scanner
    CppWordScanner scanner(fn.GetFullPath());

    // get the current file states
    TextStatesPtr states = scanner.states();
    if( !states ) {
        return;
    }


    // get the local by scanning from the current function's
    TagEntryPtr tag = TagsManagerST::Get()->FunctionFromFileLine(fn, line + 1);
    if( !tag ) {
        return;
    }

    // Get the line number of the function
    int funcLine = tag->GetLine() - 1;

    // Convert the line number to offset
    int from = states->LineToPos     (funcLine);
    int to   = states->FunctionEndPos(from);

    if(to == wxNOT_FOUND)
        return;

    // search for matches in the given range
    CppTokensMap l;
    scanner.Match(symname, l, from, to);

    CppToken::List_t tokens;
    l.findTokens(symname, tokens);
    if (tokens.empty())
        return;

    // Loop over the matches
    // Incase we did manage to resolve the word, it means that it is NOT a local variable (DoResolveWord only wors for globals NOT for locals)
    RefactorSource target;
    std::list<CppToken>::iterator iter = tokens.begin();
    for (; iter != tokens.end(); iter++) {
        wxFileName f( iter->getFilename() );
        if (!DoResolveWord(states, wxFileName(iter->getFilename()), iter->getOffset(), line, symname, &target)) {
            m_candidates.push_back( *iter );
        }
    }
}
Beispiel #4
0
void CppTokensMap::addToken(const wxString& name, const CppToken::List_t &list)
{
    // try to locate an entry with this name
    std::map<wxString, std::list<CppToken>* >::iterator iter = m_tokens.find( name );
    std::list<CppToken> *tokensList(NULL);
    if (iter != m_tokens.end()) {
        tokensList = iter->second;
    } else {
        // create new list and add it to the map
        tokensList = new std::list<CppToken>;
        m_tokens.insert( std::make_pair(name, tokensList) );
    }
    tokensList->insert(tokensList->end(), list.begin(), list.end());
}
Beispiel #5
0
CppToken::List_t CppToken::loadByName(wxSQLite3Database* db, const wxString& name)
{
    CppToken::List_t matches;
    try {
        wxSQLite3Statement st = db->PrepareStatement("select * from TOKENS_TABLE where NAME=?");
        st.Bind(1, name);
        wxSQLite3ResultSet res = st.ExecuteQuery();
        while ( res.NextRow() ) {
            CppToken token(res);
            matches.push_back( token );
        }
        
    } catch (wxSQLite3Exception &e) {
        wxUnusedVar( e );
    }
    return matches;
}
CppToken::List_t RefactoringStorage::GetTokens(const wxString& symname, const wxFileList_t& filelist)
{
    if ( !IsCacheReady() ) {
        return CppToken::List_t();
    }

    CppToken::List_t tokens = CppToken::loadByName(&m_db, symname);

    // Include only tokens which belongs to the current list of files
    // unless the filelist is empty and in this case, we ignore this filter
    if ( filelist.empty() ) {
        return tokens;
    }

    CppToken::List_t::iterator iter = std::remove_if(tokens.begin(), tokens.end(), CppToken::RemoveIfNotIn(filelist));
    tokens.resize(std::distance(tokens.begin(), iter));
    return tokens;
}
Beispiel #7
0
void RefactoringEngine::DoFindReferences(const wxString& symname, const wxFileName& fn, int line, int pos, const wxFileList_t& files, bool onlyDefiniteMatches)
{
    // Clear previous results
    Clear();
    
    if ( ! m_storage.IsCacheReady() ) {
        m_storage.InitializeCache( files );
        return;
    }
    
    // Container for the results found in the 'files'
    CppTokensMap tokensMap;

    // Load the file and get a state map + the text from the scanner
    CppWordScanner scanner(fn.GetFullPath());

    // get the current file states
    TextStatesPtr states = scanner.states();
    if(!states)
        return;

    // Attempt to understand the expression that the caret is currently located at (using line:pos:file)
    RefactorSource rs;
    if(!DoResolveWord(states, fn, pos + symname.Len(), line, symname, &rs))
        return;

    wxFileList_t modifiedFilesList = m_storage.FilterUpToDateFiles( files );
    clProgressDlg* prgDlg = NULL;
    if ( !modifiedFilesList.empty() ) {
        prgDlg = CreateProgressDialog(_("Updating cache..."), files.size());
        // Search the provided input files for the symbol to rename and prepare
        // a CppTokensMap
        for (size_t i=0; i<modifiedFilesList.size(); i++) {
            wxFileName curfile = modifiedFilesList.at(i);

            wxString msg;
            msg << _("Caching file: ") << curfile.GetFullName();
            // update the progress bar
            if (!prgDlg->Update(i, msg)) {
                prgDlg->Destroy();
                Clear();
                return;
            }

            // Scan only valid C / C++ files
            switch(FileExtManager::GetType(curfile.GetFullName())) {
            case FileExtManager::TypeHeader:
            case FileExtManager::TypeSourceC:
            case FileExtManager::TypeSourceCpp: {
                // load matches for a give symbol
                m_storage.Match(symname, curfile.GetFullPath(), tokensMap);
            }
            break;
            default:
                break;
            }
        }
        prgDlg->Destroy();
    }
    // load all tokens, first we need to parse the workspace files...
    CppToken::List_t tokens = m_storage.GetTokens(symname, files);
    if (tokens.empty())
        return;

    // sort the tokens
    tokens.sort();

    RefactorSource target;
    std::list<CppToken>::iterator iter = tokens.begin();
    int counter(0);

    TextStatesPtr statesPtr(NULL);
    wxString      statesPtrFileName;
    prgDlg = CreateProgressDialog(_("Stage 2/2: Parsing matches..."), (int) tokens.size());

    for (; iter != tokens.end(); ++iter) {

        // TODO :: send an event here to report our progress
        wxFileName f( iter->getFilename() );
        wxString   msg;
        msg << _("Parsing expression ") << counter << wxT("/") << tokens.size() << _(" in file: ") << f.GetFullName();
        if ( !prgDlg->Update(counter, msg) ) {
            // user clicked 'Cancel'
            Clear();
            prgDlg->Destroy();
            return;
        }

        counter++;
        // reset the result
        target.Reset();

        if(!statesPtr || statesPtrFileName != iter->getFilename() ) {
            // Create new statesPtr
            CppWordScanner sc(iter->getFilename());
            statesPtr         = sc.states();
            statesPtrFileName = iter->getFilename();
        }

        if(!statesPtr)
            continue;

        if (DoResolveWord(statesPtr, wxFileName( iter->getFilename() ), iter->getOffset(), iter->getLineNumber(), symname, &target)) {

            // set the line number
            if(statesPtr->states.size() > iter->getOffset())
                iter->setLineNumber( statesPtr->states[iter->getOffset()].lineNo );

            if (target.name == rs.name && target.scope == rs.scope) {
                // full match
                m_candidates.push_back( *iter );

            } else if (target.name == rs.scope && !rs.isClass) {
                // source is function, and target is class
                m_candidates.push_back( *iter );

            } else if (target.name == rs.name && rs.isClass) {
                // source is class, and target is ctor
                m_candidates.push_back( *iter );

            } else if (!onlyDefiniteMatches) {
                // add it to the possible match list
                m_possibleCandidates.push_back( *iter );
            }
        } else if( !onlyDefiniteMatches) {
            // resolved word failed, add it to the possible list
            m_possibleCandidates.push_back( *iter );
        }
    }

    prgDlg->Destroy();
}