コード例 #1
0
ファイル: PHPExpression.cpp プロジェクト: avesus/codelite
PHPEntityBase::Ptr_t PHPExpression::Resolve(PHPLookupTable& lookpTable, const wxString& sourceFileName)
{
    if(m_expression.empty()) return PHPEntityBase::Ptr_t(NULL);

    PHPSourceFile source(m_text);
    source.SetParseFunctionBody(true);
    source.SetFilename(sourceFileName);
    source.Parse();
    wxString asString = SimplifyExpression(source, 0);
    
    // Now, use the lookup table
    std::list<PHPExpression::Part>::iterator iter = m_parts.begin();
    PHPEntityBase::Ptr_t currentToken(NULL);
    for(; iter != m_parts.end(); ++iter) {
        if(!currentToken) {
            // first token
            currentToken = lookpTable.FindScope(iter->m_text);
            
        } else {
            // load the children of the current token (optionally, filter by the text)
            currentToken = lookpTable.FindMemberOf(currentToken->GetDbId(), iter->m_text);
        }
        if(!currentToken) {
            // return NULL
            return currentToken;
        }
    }
    return currentToken;
}
コード例 #2
0
void PHPParserThread::ParseFile(PHPParserThreadRequest* request)
{
    wxFileName fnWorkspaceFile(request->workspaceFile);
    PHPLookupTable lookuptable;
    lookuptable.Open(fnWorkspaceFile.GetPath());

    // Parse the source file
    PHPSourceFile sourceFile(wxFileName(request->file));
    sourceFile.SetParseFunctionBody(false);
    sourceFile.Parse();

    // Save its symbols
    lookuptable.UpdateSourceFile(sourceFile);
}
コード例 #3
0
void PHPParserThread::ParseFiles(PHPParserThreadRequest* request)
{
    wxFileName fnWorkspaceFile(request->workspaceFile);
    bool isFull = request->requestType == PHPParserThreadRequest::kParseWorkspaceFilesFull;
    wxUnusedVar(isFull);

    wxStringSet_t uniqueFilesSet;
    uniqueFilesSet.insert(request->files.begin(), request->files.end());

    // Open the database
    PHPLookupTable lookuptable;
    lookuptable.Open(fnWorkspaceFile.GetPath());

    for(size_t i = 0; i < request->frameworksPaths.GetCount(); ++i) {
        if(ms_goingDown) {
            ms_goingDown = false;
            return;
        }
        wxArrayString frameworkFiles;
        wxDir::GetAllFiles(request->frameworksPaths.Item(i), &frameworkFiles, "*.php", wxDIR_DIRS | wxDIR_FILES);
        uniqueFilesSet.insert(frameworkFiles.begin(), frameworkFiles.end());
    }

    // Convert the set back to array
    wxArrayString allFiles;
    wxStringSet_t::iterator iter = uniqueFilesSet.begin();
    for(; iter != uniqueFilesSet.end(); ++iter) {
        allFiles.Add(*iter);
    }

    // Get list of PHP files under
    lookuptable.RecreateSymbolsDatabase(allFiles,
                                        request->requestType == PHPParserThreadRequest::kParseWorkspaceFilesFull ?
                                            PHPLookupTable::kUpdateMode_Full :
                                            PHPLookupTable::kUpdateMode_Fast,
                                        [&]() { return PHPParserThread::ms_goingDown; },
                                        false);
    // reset the shutdown flag
    ms_goingDown = false;
}
コード例 #4
0
ファイル: PHPExpression.cpp プロジェクト: Alexpux/codelite
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;
}
コード例 #5
0
ファイル: PHPExpression.cpp プロジェクト: Alexpux/codelite
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);
}
コード例 #6
0
ファイル: PHPExpression.cpp プロジェクト: Alexpux/codelite
PHPEntityBase::Ptr_t PHPExpression::Resolve(PHPLookupTable& lookpTable, const wxString& sourceFileName)
{
    if(m_expression.empty()) return PHPEntityBase::Ptr_t(NULL);

    m_sourceFile.reset(new PHPSourceFile(m_text));
    m_sourceFile->SetParseFunctionBody(true);
    m_sourceFile->SetFilename(sourceFileName);
    m_sourceFile->Parse();

    if(m_expression.size() == 1 && m_expression.at(0).type == kPHP_T_NS_SEPARATOR) {
        // user typed '\'
        return lookpTable.FindScope("\\");
    }

    wxString asString = DoSimplifyExpression(0, m_sourceFile);
    wxUnusedVar(asString);

    if(m_parts.empty() && !m_filter.IsEmpty()) {

        // We have no expression, but the user did type something...
        // Return the parent scope of what the user typed so far
        if(m_filter.Contains("\\")) {
            // A namespace separator was found in the filter, break
            // the filter into 2:
            // scope + filter
            wxString scopePart = m_filter.BeforeLast('\\');
            if(!scopePart.StartsWith("\\")) {
                scopePart.Prepend("\\");
            }

            wxString filterPart = m_filter.AfterLast('\\');

            // Adjust the filter
            m_filter.swap(filterPart);

            // Fix the scope part
            scopePart = m_sourceFile->MakeIdentifierAbsolute(scopePart);
            return lookpTable.FindScope(scopePart);

        } else {
            // No namespace separator was typed
            // try to guess:
            // if the m_filter contains "(" -> user wants a global functions
            // else we use the current file scope
            return lookpTable.FindScope(m_sourceFile->Namespace()->GetFullName());
        }
    }

    // Now, use the lookup table
    std::list<PHPExpression::Part>::iterator iter = m_parts.begin();
    PHPEntityBase::Ptr_t currentToken(NULL);
    PHPEntityBase::Ptr_t parentToken(NULL);
    for(; iter != m_parts.end(); ++iter) {
        Part& part = *iter;
        if(!currentToken) {
            // first token
            // Check locks first
            if(part.m_text.StartsWith("$") && m_sourceFile->CurrentScope()) {
                // a variable
                currentToken = m_sourceFile->CurrentScope()->FindChild(part.m_text);
            }
            if(!currentToken) {
                currentToken = lookpTable.FindScope(part.m_text);
                if(!currentToken) {
                    // If we are inside a namespace, try prepending the namespace
                    // to the first token
                    if(m_sourceFile->Namespace() && m_sourceFile->Namespace()->GetFullName() != "\\") {
                        // Not the global namespace
                        wxString fullns =
                            PHPEntityNamespace::BuildNamespace(m_sourceFile->Namespace()->GetFullName(), part.m_text);
                        // Check if it exists
                        PHPEntityBase::Ptr_t pGuess = lookpTable.FindScope(fullns);
                        if(pGuess) {
                            currentToken = pGuess;
                            part.m_text = fullns;
                        } else {
                            // Maybe its a global function..
                            currentToken = lookpTable.FindFunction(part.m_text);
                        }
                    } else {
                        // Maybe its a global function..
                        currentToken = lookpTable.FindFunction(part.m_text);
                    }
                }
            }

        } else {
            // load the children of the current token (optionally, filter by the text)
            currentToken = lookpTable.FindMemberOf(currentToken->GetDbId(), part.m_text);
            if(currentToken && currentToken->Is(kEntityTypeFunctionAlias)) {
                // If the member is a function-alias, use the actual function instead
                currentToken = currentToken->Cast<PHPEntityFunctionAlias>()->GetFunc();
            }
        }

        // If the current "part" of the expression ends with a scope resolving operator ("::") or
        // an object operator ("->") we need to resolve the operator to the actual type (
        // incase of a functin it will be the return value, and in case of a variable it will be
        // the type hint)
        if(currentToken) {
            if(part.m_operator == kPHP_T_OBJECT_OPERATOR || part.m_operator == kPHP_T_PAAMAYIM_NEKUDOTAYIM) {
                wxString actualType;
                if(currentToken->Is(kEntityTypeFunction)) {
                    // return the function return value
                    actualType = currentToken->Cast<PHPEntityFunction>()->GetReturnValue();
                } else if(currentToken->Is(kEntityTypeVariable)) {
                    // return the type hint
                    actualType = currentToken->Cast<PHPEntityVariable>()->GetTypeHint();
                }

                wxString fixedpath;
                if(!actualType.IsEmpty() && FixReturnValueNamespace(lookpTable, parentToken, actualType, fixedpath)) {
                    actualType.swap(fixedpath);
                }

                if(!actualType.IsEmpty()) {
                    currentToken = lookpTable.FindScope(actualType);
                }
            }
        }

        if(!currentToken) {
            // return NULL
            return currentToken;
        }
        parentToken = currentToken;
    }
    return currentToken;
}