Developer forums (C::B DEVELOPMENT STRICTLY!) > CodeCompletion redesign

I would like to read all the template arguments

(1/1)

ollydbg:
Currently, the CC doesn't support dealing with template.
So, what I want is (three steps):
Step One, read the information about template argument list
Step Two, store these information to each Token
Step Three, use them when doing codecompletion.

Here is what I would like to do in the first step:
There is a function named "SkipAngleBraces" in the Parserthread class. So, it can be used to read the template argument, I just change it to like:

--- Code: ---wxString ParserThread::SkipAngleBraces()
{
    // need to force the tokenizer _not_ skip anything
    // or else default values for template params would cause us to miss everything (because of the '=' symbol)
    TokenizerState oldState = m_Tokenizer.GetState();
    m_Tokenizer.SetState(tsSkipNone);
    wxString arg;

    int nestLvl = 0;
    // NOTE: only exit this loop with 'break' so the tokenizer's state can
    // be reset afterwards (i.e. don't use 'return')
    while (!TestDestroy())
    {
        wxString tmp = m_Tokenizer.GetToken();
        if (tmp==ParserConsts::lt)
        {
            arg<<tmp;
            ++nestLvl;
        }
        else if (tmp==ParserConsts::gt)
        {
            arg<<tmp;
            --nestLvl;
        }
        else if (tmp==ParserConsts::semicolon)
        {
            // unget token - leave ; on the stack
            m_Tokenizer.UngetToken();
            arg.Clear();
            break;
        }
        else if (tmp.IsEmpty())
            break;
        else
            arg<<tmp;


        if (nestLvl <= 0)
        {
            TRACE( _T("SkipAngleBraces() : file(%s) line(%d) %s"), m_Filename.wx_str(),m_Tokenizer.GetLineNumber(),arg.wx_str());
            break;
        }

    }

    // reset tokenizer's functionality
    m_Tokenizer.SetState(oldState);
    return arg;
}

--- End code ---

So, you can see, if we find a match of "<" and ">", we can return the whole string of <xxxx yyyyy zzzz...>, this string seems to be the correct template arguments.

The next step is to read the class ancestor string list, for example, see the sample code:

--- Code: ---template <typename a, typename b>
class AAA
{
    a m_a;
    b m_b;
};

template <typename a, typename b>
ccc<x,y>  BBB(a in_a, b in_b)
{
    a m_a;
    b m_b;
};

class CCC: public AAA<int,float>
{
    ;
};

--- End code ---

look at the class CCC, you can see, when we first find a "colon", we know that the next string are ancestor strings.

Currently, this is done in the void ParserThread::HandleClass(EClassType ct)

see:


--- Code: ---if (next==ParserConsts::colon) // has ancestor(s)
            {
                TRACE(_T("HandleClass() : Class '%s' has ancestors"), current.wx_str());
                m_Tokenizer.GetToken(); // eat ":"
                while (!TestDestroy())
                {
                    wxString tmp = GetClassFromMacro(m_Tokenizer.GetToken());
                    next = m_Tokenizer.PeekToken();
                    if (tmp==ParserConsts::kw_public ||
                        tmp==ParserConsts::kw_protected ||
                        tmp==ParserConsts::kw_private)
                    {
                        continue;
                    }
                    if (!(tmp==ParserConsts::comma || tmp==ParserConsts::gt))
                    {
                        // fix for namespace usage in ancestors
                        if (tmp==ParserConsts::dcolon || next==ParserConsts::dcolon)
                            ancestors << tmp;
                        else
                            ancestors << tmp << _T(',');
                        TRACE(_T("HandleClass() : Adding ancestor ") + tmp);
                    }

                    if (next.IsEmpty() ||
                        next==ParserConsts::opbrace ||
                        next==ParserConsts::semicolon)
                    {
                        break;
                    }
                    else if (next==ParserConsts::lt)
                    {
                        // template class
                        //m_Tokenizer.GetToken(); // reach "<"
                        // must not "eat" the token,
                        // SkipAngleBraces() will do it to see what it must match
                        wxString arg = SkipAngleBraces();
                        if(!arg.IsEmpty())
                        {
                            ancestors<<arg;
                        }
                        // also need to 'unget' the last token (>)
                        // so next iteration will see the { or ; in 'next'
                        m_Tokenizer.UngetToken();
                    }
                }
                TRACE(_T("HandleClass() : Ancestors: ") + ancestors);
            }

--- End code ---

the code is try to read the whole ancestor strings, but is was not fully correct, so I need more time to fix.

I'm concerning another issue:

When all the "template arguments" was correctly parsed, How can we use this information in the Step Three??

blueshake:
@all
simple template codecompletion has been supported now.

test codes:

--- Code: ---template <typename T1>

class tm1
{
    T1 tm1_xx;
    T1 tm1_yy;
};
class cls1
{
    int cls1_xx;
    int cls1_yy;
};
/**class cls2
{
    int cls2_xx;
    int cls2_yy;
};*/
tm1<cls1> tt;
tt.tm1_xx.
--- End code ---

see the picture.

ollydbg:
Nice work!!!

ollydbg:
Good news, blueshake and I was done on some template handling, see the test code:


--- Code: ---class MyClass
{
public:
    int m_x;
    int m_y;
};

template <typename T1>
class MyTemplate
{
public:
    T1 m_xx;
    T1 m_yy;
    T1 Function(int aaa);
    T1* operator->() const throw()
    {
         return ;
    }
};

// a class object
MyTemplate<MyClass> a;

// a function
MyTemplate<MyClass> GlobalFunction(int bbb){};


// works here!!
GlobalFunction().Function().m_x;

a->

--- End code ---

and the result, we are handling the overloaded operator -> function.  :D



we are doing more testing.....

Navigation

[0] Message Index

Go to full version