Author Topic: Patch 3407: correctly parse c++98 enums  (Read 19645 times)

Offline ollydbg

  • Developer
  • Lives here!
  • *****
  • Posts: 5386
  • OpenCV and Robotics
    • Chinese OpenCV forum moderator
Re: Patch 3407: correctly parse c++98 enums
« Reply #15 on: January 22, 2013, 02:25:38 pm »
How about this:
Code
Index: src/plugins/codecompletion/parser/parserthread.cpp
===================================================================
--- src/plugins/codecompletion/parser/parserthread.cpp (wersja 8785)
+++ src/plugins/codecompletion/parser/parserthread.cpp (kopia robocza)
@@ -2263,10 +2282,13 @@
     // enums have the following rough definition:
     // enum [xxx] { type1 name1 [= 1][, [type2 name2 [= 2]]] };
     bool isUnnamed = false;
+    bool isEnumClass = false;
     int lineNr = m_Tokenizer.GetLineNumber();
     wxString token = m_Tokenizer.GetToken();
-    if (token == ParserConsts::kw_class)
+    if (token == ParserConsts::kw_class){
         token = m_Tokenizer.GetToken();
+        isEnumClass = true;
+    }
     if (token.IsEmpty())
         return;
 
@@ -2357,7 +2379,8 @@
             {
                 Token* lastParent = m_LastParent;
                 m_LastParent = newEnum;
-                DoAddToken(tkEnumerator, token, m_Tokenizer.GetLineNumber());
+                Token* enumerator = DoAddToken(tkEnumerator, token, m_Tokenizer.GetLineNumber());
+                enumerator->m_Scope = isEnumClass ? tsPrivate : tsPublic;
                 m_LastParent = lastParent;
             }
             if (peek==ParserConsts::colon)
Index: src/plugins/codecompletion/nativeparser_base.h
===================================================================
--- src/plugins/codecompletion/nativeparser_base.h (wersja 8785)
+++ src/plugins/codecompletion/nativeparser_base.h (kopia robocza)
@@ -396,14 +396,16 @@
     // for GenerateResultSet()
     bool AddChildrenOfUnnamed(TokenTree* tree, const Token* parent, TokenIdxSet& result)
     {
-        if (parent->m_TokenKind == tkClass && parent->m_Name.StartsWith(g_UnnamedSymbol))
+        if (((parent->m_TokenKind & (tkClass | tkEnum)) != 0)
+            && parent->m_Name.StartsWith(g_UnnamedSymbol))
         {
             // add all its children
             for (TokenIdxSet::const_iterator it = parent->m_Children.begin();
                                              it != parent->m_Children.end(); ++it)
             {
                 Token* tokenChild = tree->at(*it);
-                if (tokenChild)
+                if (tokenChild &&
+                    (parent->m_TokenKind == tkClass || tokenChild->m_Scope != tsPrivate))
                     result.insert(*it);
             }
 
@@ -411,7 +413,25 @@
         }
         return false;
     }
+   
+    bool AddChildrenOfEnum(TokenTree* tree, const Token* parent, TokenIdxSet& result)
+    {
+        if (parent->m_TokenKind == tkEnum)
+        {
+            // add all its children
+            for (TokenIdxSet::const_iterator it = parent->m_Children.begin();
+                                             it != parent->m_Children.end(); ++it)
+            {
+                Token* tokenChild = tree->at(*it);
+                if (tokenChild && tokenChild->m_Scope != tsPrivate)
+                    result.insert(*it);
+            }
 
+            return true;
+        }
+        return false;
+    }
+
     // for GenerateResultSet()
     bool MatchText(const wxString& text, const wxString& target, bool caseSens, bool isPrefix)
     {
Index: src/plugins/codecompletion/nativeparser_base.cpp
===================================================================
--- src/plugins/codecompletion/nativeparser_base.cpp (wersja 8785)
+++ src/plugins/codecompletion/nativeparser_base.cpp (kopia robocza)
@@ -1318,7 +1318,11 @@
                 if (!token)
                     continue;
                 if ( !AddChildrenOfUnnamed(tree, token, result) )
+                {
                     result.insert(*it);
+                    AddChildrenOfEnum(tree, token, result);
+                }
+                   
             }
 
             tree->RecalcInheritanceChain(parent);
@@ -1334,7 +1338,10 @@
                     if (!token)
                         continue;
                     if ( !AddChildrenOfUnnamed(tree, token, result) )
+                    {
                         result.insert(*it2);
+                        AddChildrenOfEnum(tree, token, result);
+                    }
                 }
             }
         }


Here is my test result of this patch:
Using the test file: trunk\src\plugins\codecompletion\testing\structs_typedefs_enums.cpp (rev 8811)

Code
//    SEnum:: OK
//    SEnum::ELocal:: OK
//    SEnum::eEnumClassLocal:: Fail
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: 5386
  • OpenCV and Robotics
    • Chinese OpenCV forum moderator
Re: Patch 3407: correctly parse c++98 enums
« Reply #16 on: January 22, 2013, 02:43:32 pm »
//    SEnum::eEnumClassLocal:: Fail
It looks like this is the expect behavior. I see the code:
Code
    while (IS_ALIVE)
    {
        // process enumerators
        token = m_Tokenizer.GetToken();
        wxString peek = m_Tokenizer.PeekToken();
        if (token.IsEmpty() || peek.IsEmpty())
            return; //eof
        if (token==ParserConsts::clbrace && level == m_Tokenizer.GetNestingLevel())
            break;
        // assignments (=xxx) are ignored by the tokenizer,
        // so we don't have to worry about them here ;)
        if (peek==ParserConsts::comma || peek==ParserConsts::clbrace || peek==ParserConsts::colon)
        {
            // this "if", avoids non-valid enumerators
            // like a comma (if no enumerators follow)
            if (   wxIsalpha(token.GetChar(0))
                || (token.GetChar(0) == ParserConsts::underscore_chr) )
            {
                Token* lastParent = m_LastParent;
                m_LastParent = newEnum;
                Token* enumerator = DoAddToken(tkEnumerator, token, m_Tokenizer.GetLineNumber());
                enumerator->m_Scope = isEnumClass ? tsPrivate : tsPublic;
                m_LastParent = lastParent;
            }
            if (peek==ParserConsts::colon)
            {
                // bit specifier (eg, xxx:1)
                // -> walk to , or }
                SkipToOneOfChars(ParserConsts::commaclbrace);
            }
        }
    }

Here:
Code
enumerator->m_Scope = isEnumClass ? tsPrivate : tsPublic;

The added enumerator is "private".

But it looks like the private members are not added to codecompletion suggestion list.
Code
    bool AddChildrenOfEnum(TokenTree* tree, const Token* parent, TokenIdxSet& result)
    {
        if (parent->m_TokenKind == tkEnum)
        {
            // add all its children
            for (TokenIdxSet::const_iterator it = parent->m_Children.begin();
                                             it != parent->m_Children.end(); ++it)
            {
                Token* tokenChild = tree->at(*it);
                if (tokenChild && tokenChild->m_Scope != tsPrivate)
                    result.insert(*it);
            }

            return true;
        }
        return false;
    }

Here, only members those are "Not private" are added to the result.
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 p2rkw

  • Almost regular
  • **
  • Posts: 142
Re: Patch 3407: correctly parse c++98 enums
« Reply #17 on: January 22, 2013, 02:47:22 pm »
@ollydbg:
replace
Code
SEnum::eEnumClassLocal::
with
Code
SEnum::EEnumClassLocal::

Offline ollydbg

  • Developer
  • Lives here!
  • *****
  • Posts: 5386
  • OpenCV and Robotics
    • Chinese OpenCV forum moderator
Re: Patch 3407: correctly parse c++98 enums
« Reply #18 on: January 22, 2013, 02:50:52 pm »
@ollydbg:
replace
Code
SEnum::eEnumClassLocal::
with
Code
SEnum::EEnumClassLocal::
Yes, I also see this typo, after change this, I see it list three members.
But I'm using the code:
Code
    bool AddChildrenOfEnum(TokenTree* tree, const Token* parent, TokenIdxSet& result)
    {
        if (parent->m_TokenKind == tkEnum)
        {
            // add all its children
            for (TokenIdxSet::const_iterator it = parent->m_Children.begin();
                                             it != parent->m_Children.end(); ++it)
            {
                Token* tokenChild = tree->at(*it);
                if (tokenChild )//&& tokenChild->m_Scope != tsPrivate)
                    result.insert(*it);
            }

            return true;
        }
        return false;
    }

I will test your patch again.

EDIT: your patch works fine, all three tests were OK.
« Last Edit: January 22, 2013, 02:53:05 pm by ollydbg »
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 MortenMacFly

  • Administrator
  • Lives here!
  • *****
  • Posts: 9615
Re: Patch 3407: correctly parse c++98 enums
« Reply #19 on: January 22, 2013, 09:25:07 pm »
EDIT: your patch works fine, all three tests were OK.
Keep in mind that there are way more enums defined in this test file than only 3. These 3 commented cases are just for convenience (and because I was too lazy to type them all). But all enums should pass.
Compiler logging: Settings->Compiler & Debugger->tab "Other"->Compiler logging="Full command line"
C::B Manual: http://www.codeblocks.org/docs/main_codeblocks_en.html
C::B FAQ: http://wiki.codeblocks.org/index.php?title=FAQ

Offline oBFusCATed

  • Developer
  • Lives here!
  • *****
  • Posts: 13438
    • Travis build status
Re: Patch 3407: correctly parse c++98 enums
« Reply #20 on: January 29, 2013, 10:33:42 pm »
Any problems encountered? If no, I'll commit in the next couple of days.
(most of the time I ignore long posts)
[strangers don't send me private messages, I'll ignore them; post a topic in the forum, but first read the rules!]

Offline ollydbg

  • Developer
  • Lives here!
  • *****
  • Posts: 5386
  • OpenCV and Robotics
    • Chinese OpenCV forum moderator
Re: Patch 3407: correctly parse c++98 enums
« Reply #21 on: January 31, 2013, 04:20:51 am »
Any problems encountered? If no, I'll commit in the next couple of days.
I'm OK with this patch. All enum testes work fine
Code
//    EGlobalCommented::
//    EGlobal::
//    EGlobalAssign::
//    EEnumClassGlobal::
//    SEnum::
//    SEnum::ELocal::
//    SEnum::EEnumClassLocal::
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.