Exemple #1
0
void PHPSourceFile::Parse(int exitDepth)
{
    int retDepth = exitDepth;
    phpLexerToken token;
    while(NextToken(token)) {
        switch(token.type) {
        case '=':
            m_lookBackTokens.clear();
            break;
        case '{':
            m_lookBackTokens.clear();
            break;
        case '}':
            m_lookBackTokens.clear();
            if(m_depth == retDepth) {
                return;
            }
            break;
        case ';':
            m_lookBackTokens.clear();
            break;
        case kPHP_T_VARIABLE:
            if(!CurrentScope()->Is(kEntityTypeClass)) {
                // A global variable
                OnVariable(token);
            }
            break;
        case kPHP_T_CATCH:
            // found 'catch (...)'
            OnCatch();
            break;
        case kPHP_T_PUBLIC:
        case kPHP_T_PRIVATE:
        case kPHP_T_PROTECTED: {
            int visibility = token.type;
            PHPEntityClass* cls = CurrentScope()->Cast<PHPEntityClass>();
            if(cls) {
                /// keep the current token
                m_lookBackTokens.push_back(token);

                // Now we have a small problem here:
                // public can be a start for a member or a function
                // we let the lexer run forward until it finds kPHP_T_VARIABLE (for variable)
                // or kPHP_T_IDENTIFIER
                int what = ReadUntilFoundOneOf(kPHP_T_VARIABLE, kPHP_T_FUNCTION, token);
                if(what == kPHP_T_VARIABLE) {
                    // A variable
                    PHPEntityBase::Ptr_t member(new PHPEntityVariable());
                    member->SetFilename(m_filename.GetFullPath());
                    member->Cast<PHPEntityVariable>()->SetVisibility(visibility);
                    member->Cast<PHPEntityVariable>()->SetFullName(token.text);
                    size_t flags = LookBackForVariablesFlags();
                    member->Cast<PHPEntityVariable>()->SetFlag(kVar_Member);
                    member->Cast<PHPEntityVariable>()->SetFlag(kVar_Const, flags & kVar_Const);
                    member->Cast<PHPEntityVariable>()->SetFlag(kVar_Static, flags & kVar_Static);
                    member->Cast<PHPEntityVariable>()->SetLine(token.lineNumber);
                    CurrentScope()->AddChild(member);

                    // Handle member assignment
                    // public $memberVar = new Something();
                    // for such cases, assign $memberVar type of Something()
                    phpLexerToken t;
                    if(!NextToken(t)) {
                        // EOF
                        return;
                    }

                    if(t.type == '=') {
                        // assignment
                        wxString expr;
                        if(!ReadExpression(expr)) {
                            return;
                        }

                        // Optimize 'new ClassName(..)' expression
                        if(expr.StartsWith("new")) {
                            expr = expr.Mid(3);
                            expr.Trim().Trim(false);
                            expr = expr.BeforeFirst('(');
                            expr.Trim().Trim(false);
                            member->Cast<PHPEntityVariable>()->SetTypeHint(MakeIdentifierAbsolute(expr));

                        } else {
                            // keep the expression
                            member->Cast<PHPEntityVariable>()->SetExpressionHint(expr);
                        }

                    } else {
                        // restore the token
                        UngetToken(t);
                        if(!ConsumeUntil(';')) return;
                    }

                } else if(what == kPHP_T_FUNCTION) {
                    // A function...
                    OnFunction();
                    m_lookBackTokens.clear();
                }
            }
            break;
        }
        case kPHP_T_DEFINE:
            // Define statement
            OnDefine(token);
            break;
        case kPHP_T_CONST:
            OnConstant(token);
            break;
        case kPHP_T_REQUIRE:
        case kPHP_T_REQUIRE_ONCE:
        case kPHP_T_INCLUDE:
        case kPHP_T_INCLUDE_ONCE:
            // Handle include files
            m_lookBackTokens.clear();
            break;
        case kPHP_T_FOREACH:
            // found "foreach" statement
            OnForEach();
            m_lookBackTokens.clear();
            break;
        case kPHP_T_USE:
            // Found outer 'use' statement - construct the alias table
            if(Class()) {
                // inside a class, this means that this is a 'use <trait>;'
                OnUseTrait();
            } else {
                // alias table
                OnUse();
            }
            m_lookBackTokens.clear();
            break;
        case kPHP_T_CLASS:
        case kPHP_T_INTERFACE:
        case kPHP_T_TRAIT:
            // Found class
            OnClass(token);
            m_lookBackTokens.clear();
            break;
        case kPHP_T_NAMESPACE:
            // Found a namespace
            OnNamespace();
            m_lookBackTokens.clear();
            break;
        case kPHP_T_FUNCTION:
            // Found function
            OnFunction();
            m_lookBackTokens.clear();
            break;
        default:
            // Keep the token
            break;
        }
    }
    PhaseTwo();
}
void PHPSourceFile::Parse(int exitDepth)
{
    int retDepth = exitDepth;
    phpLexerToken token;
    while(NextToken(token)) {
        switch(token.type) {
        case '=':
            m_lookBackTokens.clear();
            break;
        case '{':
            m_lookBackTokens.clear();
            break;
        case '}':
            m_lookBackTokens.clear();
            if(m_depth == retDepth) {
                return;
            }
            break;
        case ';':
            m_lookBackTokens.clear();
            break;
        case kPHP_T_VARIABLE:
            if(!CurrentScope()->Is(kEntityTypeClass)) {
                // A global variable
                OnVariable(token);
            }
            break;
        case kPHP_T_CATCH:
            // found 'catch (...)'
            OnCatch();
            break;
        case kPHP_T_PUBLIC:
        case kPHP_T_PRIVATE:
        case kPHP_T_PROTECTED: {
            int visibility = token.type;
            PHPEntityClass* cls = CurrentScope()->Cast<PHPEntityClass>();
            if(cls) {
                /// keep the current token
                m_lookBackTokens.push_back(token);

                // Now we have a small problem here:
                // public can be a start for a member or a function
                // we let the lexer run forward until it finds kPHP_T_VARIABLE (for variable)
                // or kPHP_T_IDENTIFIER
                int what = ReadUntilFoundOneOf(kPHP_T_VARIABLE, kPHP_T_FUNCTION, token);
                if(what == kPHP_T_VARIABLE) {
                    // A variable
                    PHPEntityBase::Ptr_t member(new PHPEntityVariable());
                    member->SetFilename(m_filename.GetFullPath());
                    PHPEntityVariable* var = member->Cast<PHPEntityVariable>();
                    var->SetVisibility(visibility);
                    var->SetFullName(token.text);
                    size_t flags = LookBackForVariablesFlags();
                    var->SetFlag(kVar_Member);
                    var->SetFlag(kVar_Const, flags & kVar_Const);
                    var->SetFlag(kVar_Static, flags & kVar_Static);
                    var->SetLine(token.lineNumber);
                    CurrentScope()->AddChild(member);
                    if(!ConsumeUntil(';')) return;
                } else if(what == kPHP_T_FUNCTION) {
                    // A function...
                    OnFunction();
                    m_lookBackTokens.clear();
                }
            }
            break;
        }
        case kPHP_T_DEFINE:
            // Define statement
            OnDefine(token);
            break;
        case kPHP_T_CONST:
            if(ReadUntilFound(kPHP_T_IDENTIFIER, token)) {
                // constant
                PHPEntityBase::Ptr_t member(new PHPEntityVariable());
                member->SetFilename(m_filename.GetFullPath());
                PHPEntityVariable* var = member->Cast<PHPEntityVariable>();
                var->SetFullName(token.text);
                var->SetLine(token.lineNumber);
                var->SetFlag(kVar_Member);
                var->SetFlag(kVar_Const);
                CurrentScope()->AddChild(member);
                if(!ConsumeUntil(';')) return;
            }
            break;
        case kPHP_T_REQUIRE:
        case kPHP_T_REQUIRE_ONCE:
        case kPHP_T_INCLUDE:
        case kPHP_T_INCLUDE_ONCE:
            // Handle include files
            m_lookBackTokens.clear();
            break;
        case kPHP_T_USE:
            // Found outer 'use' statement - construct the alias table
            if(Class()) {
                // inside a class, this means that this is a 'use <trait>;'
                OnUseTrait();
            } else {
                // alias table
                OnUse();
            }
            m_lookBackTokens.clear();
            break;
        case kPHP_T_CLASS:
        case kPHP_T_INTERFACE:
        case kPHP_T_TRAIT:
            // Found class
            OnClass(token);
            m_lookBackTokens.clear();
            break;
        case kPHP_T_NAMESPACE:
            // Found a namespace
            OnNamespace();
            m_lookBackTokens.clear();
            break;
        case kPHP_T_FUNCTION:
            // Found function
            OnFunction();
            m_lookBackTokens.clear();
            break;
        default:
            // Keep the token
            break;
        }
    }
    PhaseTwo();
}