Author Topic: I would like to read all the template arguments  (Read 4137 times)

Offline ollydbg

  • Developer
  • Lives here!
  • *****
  • Posts: 5316
  • OpenCV and Robotics
    • Chinese OpenCV forum moderator
I would like to read all the template arguments
« on: July 06, 2010, 04:06:10 am »
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;
}

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>
{
    ;
};

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);
            }

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??
If some piece of memory should be reused, turn them to variables (or const variables).
If some piece of operations should be reused, turn them to functions.
If they happened together, then turn them to classes.

Offline blueshake

  • Regular
  • ***
  • Posts: 459
Re: I would like to read all the template arguments
« Reply #1 on: July 08, 2010, 04:55:18 am »
@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.

see the picture.
Keep low and hear the sadness of little dog.
I fall in love with a girl,but I don't dare to tell her.What should I do?

Offline ollydbg

  • Developer
  • Lives here!
  • *****
  • Posts: 5316
  • OpenCV and Robotics
    • Chinese OpenCV forum moderator
Re: I would like to read all the template arguments
« Reply #2 on: July 08, 2010, 05:10:34 am »
Nice work!!!
If some piece of memory should be reused, turn them to variables (or const variables).
If some piece of operations should be reused, turn them to functions.
If they happened together, then turn them to classes.

Offline ollydbg

  • Developer
  • Lives here!
  • *****
  • Posts: 5316
  • OpenCV and Robotics
    • Chinese OpenCV forum moderator
Re: I would like to read all the template arguments
« Reply #3 on: July 30, 2010, 03:13:47 am »
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->

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



we are doing more testing.....
If some piece of memory should be reused, turn them to variables (or const variables).
If some piece of operations should be reused, turn them to functions.
If they happened together, then turn them to classes.