示例#1
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 );
        }
    }
}
示例#2
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();
}