예제 #1
0
void PHPCodeCompletion::OnCodeComplete(clCodeCompletionEvent& e)
{
    e.Skip(true);
    if(PHPWorkspace::Get()->IsOpen()) {
        IEditor* editor = dynamic_cast<IEditor*>(e.GetEditor());
        if(editor && IsPHPFile(editor)) {
            e.Skip(false);

            // Update the settings
            TagsOptionsData d;
            clConfig ccConfig("code-completion.conf");
            ccConfig.ReadItem(&d);
            m_lookupTable.SetSizeLimit(d.GetCcNumberOfDisplayItems());

            // Check if the code completion was triggered due to user
            // typing '(', in this case, call OnFunctionCallTip()
            wxChar charAtPos = editor->GetCharAtPos(editor->GetCurrentPosition() - 1);
            if(charAtPos == '(') {
                OnFunctionCallTip(e);

            } else {
                // Perform the code completion here
                PHPExpression::Ptr_t expr(new PHPExpression(editor->GetTextRange(0, e.GetPosition())));
                bool isExprStartsWithOpenTag = expr->IsExprStartsWithOpenTag();
                PHPEntityBase::Ptr_t entity = expr->Resolve(m_lookupTable, editor->GetFileName().GetFullPath());
                if(entity) {
                    // Suggets members for the resolved entity
                    PHPEntityBase::List_t matches;
                    expr->Suggest(entity, m_lookupTable, matches);
                    if(!expr->GetFilter().IsEmpty() && (expr->GetCount() == 0)) {

                        // Word completion
                        PHPEntityBase::List_t keywords = PhpKeywords(expr->GetFilter());

                        // Preprend the keywords
                        matches.insert(matches.end(), keywords.begin(), keywords.end());

                        // Did user typed "<?ph" or "<?php" ??
                        // If so, clear the matches
                        if(isExprStartsWithOpenTag && (expr->GetFilter() == "ph" || expr->GetFilter() == "php")) {
                            matches.clear();
                        }
                    }

                    // Remove duplicates from the list
                    if(!matches.empty()) {
                        // Show the code completion box
                        DoShowCompletionBox(matches, expr);
                    }
                }
            }
        }
    }
}
예제 #2
0
void PHPCodeCompletion::DoShowCompletionBox(const PHPEntityBase::List_t& entries, PHPExpression::Ptr_t expr)
{
    wxCodeCompletionBoxEntry::Vec_t ccEntries;
    TagEntryPtrVector_t tags;
    wxStringSet_t uniqueEntries;

    // search for the old item
    PHPEntityBase::List_t::const_iterator iter = entries.begin();
    for(; iter != entries.end(); ++iter) {
        PHPEntityBase::Ptr_t entry = *iter;
        if(uniqueEntries.count(entry->GetFullName()) == 0) {
            uniqueEntries.insert(entry->GetFullName());
        } else {
            // don't add duplicate entries
            continue;
        }

        PHPEntityBase::Ptr_t ns = expr->GetSourceFile()->Namespace(); // the namespace at the source file
        TagEntryPtr t = DoPHPEntityToTagEntry(entry);

        tags.push_back(t);
    }

    std::sort(tags.begin(), tags.end(), _SAscendingSort());
    for(size_t i = 0; i < tags.size(); ++i) {
        wxCodeCompletionBoxEntry::Ptr_t ccEntry = wxCodeCompletionBox::TagToEntry(tags.at(i));
        ccEntry->SetComment(tags.at(i)->GetComment());
        ccEntries.push_back(ccEntry);
    }
    wxCodeCompletionBoxManager::Get().ShowCompletionBox(
        m_manager->GetActiveEditor()->GetCtrl(), ccEntries, wxCodeCompletionBox::kRefreshOnKeyType, wxNOT_FOUND);
}
예제 #3
0
void PHPCodeCompletion::DoShowCompletionBox(const PHPEntityBase::List_t& entries, PHPExpression::Ptr_t expr)
{
    std::vector<TagEntryPtr> tags;
    wxStringSet_t uniqueEntries;

    // search for the old item
    PHPEntityBase::List_t::const_iterator iter = entries.begin();
    for(; iter != entries.end(); ++iter) {
        PHPEntityBase::Ptr_t entry = *iter;
        if(uniqueEntries.count(entry->GetFullName()) == 0) {
            uniqueEntries.insert(entry->GetFullName());
        } else {
            // don't add duplicate entries
            continue;
        }

        PHPEntityBase::Ptr_t ns = expr->GetSourceFile()->Namespace(); // the namespace at the source file
        TagEntryPtr t = DoPHPEntityToTagEntry(entry);
        t->SetUserData(new PHPCCUserData(entry));
        tags.push_back(t);
    }

    if(tags.empty()) return;

    std::sort(tags.begin(), tags.end(), _SAscendingSort());
    m_manager->GetActiveEditor()->ShowCompletionBox(tags, expr->GetFilter(), false, this);
}
예제 #4
0
bool PHPRefactoring::FindByName(const PHPEntityBase::List_t& entries, const wxString& name) const
{
    PHPEntityBase::List_t::const_iterator iter = entries.begin();
    for(; iter != entries.end(); ++iter) {
        if((*iter)->GetFullName() == name) {
            return true;
        }
    }
    return false;
}
예제 #5
0
void PHPExpression::DoMakeUnique(PHPEntityBase::List_t& matches)
{
    std::set<wxString> uniqueNames;
    PHPEntityBase::List_t uniqueList;
    for(PHPEntityBase::List_t::iterator iter = matches.begin(); iter != matches.end(); ++iter) {
        if(uniqueNames.count((*iter)->GetFullName()) == 0) {
            uniqueNames.insert((*iter)->GetFullName());
            uniqueList.push_back(*iter);
        }
    }
    matches.swap(uniqueList);
}
예제 #6
0
void PHPCodeCompletion::OnFindSymbol(clCodeCompletionEvent& e)
{
    e.Skip();
    if(PHPWorkspace::Get()->IsOpen()) {
        if(!CanCodeComplete(e)) return;
        e.Skip(false);
        IEditor* editor = dynamic_cast<IEditor*>(e.GetEditor());
        if(editor) {
            wxString word = editor->GetWordAtCaret();
            if(word.IsEmpty()) return;
            PHPEntityBase::List_t symbols = m_lookupTable.FindSymbol(word);
            if(symbols.size() == 1) {
                PHPEntityBase::Ptr_t match = *symbols.begin();
                DoOpenEditorForEntry(match);

            } else {

                // Convert the matches to clSelectSymbolDialogEntry::List_t
                clSelectSymbolDialogEntry::List_t entries;
                std::for_each(symbols.begin(), symbols.end(), [&](PHPEntityBase::Ptr_t entry) {
                    TagEntryPtr tag = DoPHPEntityToTagEntry(entry);
                    wxBitmap bmp = wxCodeCompletionBox::GetBitmap(tag);

                    clSelectSymbolDialogEntry m;
                    m.bmp = bmp;
                    m.name = entry->GetFullName();
                    m.clientData = new PHPFindSymbol_ClientData(entry);
                    m.help = tag->GetKind();
                    entries.push_back(m);
                });

                // Show selection dialog
                clSelectSymbolDialog dlg(EventNotifier::Get()->TopFrame(), entries);
                if(dlg.ShowModal() != wxID_OK) return;
                PHPFindSymbol_ClientData* cd = dynamic_cast<PHPFindSymbol_ClientData*>(dlg.GetSelection());
                if(cd) {
                    DoOpenEditorForEntry(cd->m_ptr);
                }
            }
        }
    }
}
예제 #7
0
void OpenResourceDlg::DoGetResources(const wxString& filter)
{
    m_resources.clear();

    PHPEntityBase::List_t matches;
    m_table.LoadAllByFilter(matches, filter);

    // Convert the PHP matches into resources
    PHPEntityBase::List_t::iterator iter = matches.begin();
    m_resources.reserve(matches.size());
    for(; iter != matches.end(); ++iter) {
        PHPEntityBase::Ptr_t match = *iter;
        if(FileUtils::FuzzyMatch(filter, match->GetFullName())) {
            ResourceItem resource;
            resource.displayName = match->GetDisplayName();
            resource.filename = match->GetFilename();
            resource.line = match->GetLine();
            resource.SetType(match);
            m_resources.push_back(resource);
        }
    }
}
예제 #8
0
void PHPExpression::Suggest(PHPEntityBase::Ptr_t resolved, PHPLookupTable& lookup, PHPEntityBase::List_t& matches)
{
    // sanity
    if(!resolved) return;
    PHPEntityBase::Ptr_t currentScope = GetSourceFile()->CurrentScope();

    // GetCount() == 0 && !GetFilter().IsEmpty() i.e. a word completion is required.
    // We enhance the list with the following:
    // - PHP keywords
    // - Global functions
    // - Global constants
    // - Function arguments
    // - Local variables (of the current scope)
    // - And aliases e.g. 'use foo\bar as Bar;'
    if(GetCount() == 0 && !GetFilter().IsEmpty()) {

        // For functions and constants, PHP will fall back to global functions or constants if a
        // namespaced function or constant does not exist.
        PHPEntityBase::List_t globals =
            lookup.FindGlobalFunctionAndConsts(PHPLookupTable::kLookupFlags_Contains, GetFilter());
        matches.insert(matches.end(), globals.begin(), globals.end());

        if(currentScope && (currentScope->Is(kEntityTypeFunction) || currentScope->Is(kEntityTypeNamespace))) {
            // If the current scope is a function
            // add the local variables + function arguments to the current list of matches
            const PHPEntityBase::List_t& children = currentScope->GetChildren();
            PHPEntityBase::List_t::const_iterator iter = children.begin();
            for(; iter != children.end(); ++iter) {
                PHPEntityBase::Ptr_t child = *iter;
                if(child->Is(kEntityTypeVariable) && child->GetShortName().Contains(GetFilter()) &&
                   child->GetShortName() != GetFilter()) {
                    matches.push_back(child);
                }
            }
        }

        {
            // Add aliases
            PHPEntityBase::List_t aliases = GetSourceFile()->GetAliases();
            PHPEntityBase::List_t::iterator iter = aliases.begin();
            for(; iter != aliases.end(); ++iter) {
                if((*iter)->GetShortName().Contains(GetFilter())) {
                    matches.push_back(*iter);
                }
            }
        }

        {
            // Add $this incase we are inside a class (but only if '$this' contains the filter string)
            wxString lcFilter = GetFilter().Lower();
            if(GetSourceFile()->Class() && wxString("$this").Contains(lcFilter)) {
                PHPEntityBase::Ptr_t thiz(new PHPEntityVariable());
                thiz->SetFullName("$this");
                thiz->SetShortName("$this");
                thiz->SetFilename(currentScope->GetFilename());
                matches.push_back(thiz);
            }
        }
    }

    // Add the scoped matches
    // for the code completion
    size_t flags = PHPLookupTable::kLookupFlags_Contains | GetLookupFlags();
    if(resolved->Is(kEntityTypeClass)) {
        if(resolved->Cast<PHPEntityClass>()->IsInterface() || resolved->Cast<PHPEntityClass>()->IsAbstractClass()) {
            flags |= PHPLookupTable::kLookupFlags_IncludeAbstractMethods;
        }
    }
    
    PHPEntityBase::List_t scopeChildren = lookup.FindChildren(resolved->GetDbId(), flags, GetFilter());
    matches.insert(matches.end(), scopeChildren.begin(), scopeChildren.end());

    // Incase the resolved is a namespace, suggest all children namespaces
    if(resolved->Is(kEntityTypeNamespace)) {
        PHPEntityBase::List_t namespaces = lookup.FindNamespaces(resolved->GetFullName(), GetFilter());
        matches.insert(matches.end(), namespaces.begin(), namespaces.end());
    }

    // and make the list unique
    DoMakeUnique(matches);
}