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);
}
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);
}
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);
        }
    }
}
Example #4
0
bool PHPExpression::FixReturnValueNamespace(PHPLookupTable& lookup,
                                            PHPEntityBase::Ptr_t parent,
                                            const wxString& classFullpath,
                                            wxString& fixedpath)
{
    if(!parent) return false;
    PHPEntityBase::Ptr_t pClass = lookup.FindClass(classFullpath);
    if(!pClass) {
        // classFullpath does not exist
        // prepend the parent namespace to its path and check again
        wxString parentNamespace = parent->GetFullName().BeforeLast('\\');
        wxString returnValueNamespace = classFullpath.BeforeLast('\\');
        wxString returnValueName = classFullpath.AfterLast('\\');
        wxString newType = PHPEntityNamespace::BuildNamespace(parentNamespace, returnValueNamespace);
        newType << "\\" << returnValueName;
        pClass = lookup.FindClass(newType);
        if(pClass) {
            fixedpath = newType;
            return true;
        }
    }
    return false;
}
Example #5
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);
}
void PHPDocVisitor::OnEntity(PHPEntityBase::Ptr_t entity)
{
    // Locate a comment for this entity
    entity->SetFilename(m_sourceFile.GetFilename());

    if(!entity->GetDocComment().IsEmpty()) {
        // PHPDoc was already assigned to this entity during the parsing phase
        if(entity->Is(kEntityTypeClass)) {
            // Process @property tags here
            PHPDocComment docComment(m_sourceFile, entity->GetDocComment());
            if(!docComment.GetProperties().empty()) {
                // Got some @properties
                std::for_each(docComment.GetProperties().begin(), docComment.GetProperties().end(),
                    [&](PHPDocComment::Property::Map_t::value_type& p) {
                        PHPEntityBase::Ptr_t child = entity->FindChild(p.second.name);
                        if(!child) {
                            // No child of this type, create a new property and add it
                            child.Reset(new PHPEntityVariable());
                            child->SetFilename(m_sourceFile.GetFilename());
                            child->SetLine(entity->GetLine());
                            child->Cast<PHPEntityVariable>()->SetTypeHint(p.second.type);
                            child->Cast<PHPEntityVariable>()->SetFlag(kVar_Member); // Member variable
                            child->Cast<PHPEntityVariable>()->SetFlag(kVar_Public); // Public access
                            child->SetShortName(p.second.name);
                            child->SetFullName(p.second.name);
                            entity->AddChild(child);
                        }
                    });
            } else if(!docComment.GetMethods().empty()) {
                std::for_each(docComment.GetMethods().begin(), docComment.GetMethods().end(),
                    [&](PHPEntityBase::Ptr_t method) { entity->AddChild(method); });
            }
        }
    } else {
        // search for the comment placed at the top of the variable
        // this is why we use here -1
        int lineNum = (entity->GetLine() - 1);

        // for debugging purposes
        wxString entityName = entity->GetShortName();
        wxUnusedVar(entityName);

        std::map<int, phpLexerToken>::iterator iter = m_comments.find(lineNum);
        if(iter == m_comments.end()) {
            // try to locate a comment on the same line
            ++lineNum;
            iter = m_comments.find(lineNum);
        }

        if(iter != m_comments.end()) {

            // we got a match
            entity->SetDocComment(iter->second.Text());
            m_comments.erase(iter);

            PHPDocComment docComment(m_sourceFile, entity->GetDocComment());
            if(entity->Is(kEntityTypeFunction) && !docComment.GetReturn().IsEmpty()) {
                entity->Cast<PHPEntityFunction>()->SetReturnValue(docComment.GetReturn());
            } else if(entity->Is(kEntityTypeVariable) && !entity->Cast<PHPEntityVariable>()->IsFunctionArg()) {
                // A global variable, const or a member
                entity->Cast<PHPEntityVariable>()->SetTypeHint(docComment.GetVar());
            }

        } else if(entity->Is(kEntityTypeVariable) && entity->Parent() && entity->Parent()->Is(kEntityTypeFunction) &&
            entity->Cast<PHPEntityVariable>()->IsFunctionArg()) {
            // A function argument
            PHPDocComment docComment(m_sourceFile, entity->Parent()->GetDocComment());
            wxString typeHint = docComment.GetParam(entity->GetFullName());
            if(!typeHint.IsEmpty()) {
                entity->Cast<PHPEntityVariable>()->SetTypeHint(typeHint);
            }
        }
    }
}