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

Another completion oddity

(1/4) > >>

daniloz:
Hello all,

When trying the code below:

--- Code: ---int aaaa;
typedef struct  {
        int a;
        double b;
        int c;
        }  Tstruct;

Tstruct tttt;


void main()
{
    Tstruct bbbbb;
    int cccccc;

    bbbb

}

--- End code ---

"bbbb" gets completed automatically (as well as others) and after I enter a period ".", the list of members is shown, just as expected. So far, so good. :D

HOWEVER, if I insert "tttt." before the function main(),  "bbbb" is not completed. BUT the other variables are. Here is the problematic code:

--- Code: ---int aaaa;
typedef struct  {
        int a;
        double b;
        int c;
        }  Tstruct;

Tstruct tttt;

tttt.

void main()
{
    Tstruct bbbbb;
    int cccccc;

    bbbb

}

--- End code ---

Any hint???  :(

blueshake:
it work fine for me.  :lol:
you can download the cc-brach version and compile it by yourself.
or you can apply this patch.

note: it work for me , but i am not sure whether it will work for you ,just make a copy when you try to apply this patch.good luck. :D

--- Code: ---Index: parserthread.cpp
===================================================================
--- parserthread.cpp (revision 5730)
+++ parserthread.cpp (working copy)
@@ -465,8 +465,10 @@
                 DoParse(); // time for recursion ;)
             }
             else
-                SkipToOneOfChars(ParserConsts::semicolon); // skip externs
-//                m_Tokenizer.UngetToken(); // nope, return the token back...
+            {
+                // do nothing, just skip keyword "extern", otherwise uncomment:
+                // SkipToOneOfChars(ParserConsts::semicolon); // skip externs
+            }
             m_Str.Clear();
         }
         else if (token.StartsWith(ParserConsts::kw__asm))
@@ -519,7 +521,7 @@
         {
             m_Str.Clear();
             if (m_Options.handleClasses)
-                HandleClass();
+                HandleClass(ctClass);
             else
                 SkipToOneOfChars(ParserConsts::semicolonclbrace, true);
         }
@@ -527,7 +529,7 @@
         {
             m_Str.Clear();
             if (m_Options.handleClasses)
-                HandleClass(false);
+                HandleClass(ctStructure);
             else
                 SkipToOneOfChars(ParserConsts::semicolonclbrace, true);
         }
@@ -541,6 +543,7 @@
         }
         else if (token==ParserConsts::kw_union)
         {
+#if 0
             SkipToOneOfChars(ParserConsts::opbracesemicolon);
 //            if (m_Tokenizer.GetToken() == "{")
             {
@@ -549,6 +552,13 @@
                 m_Str.Clear();
                 m_pLastParent = oldparent;
             }
+#endif
+
+            m_Str.Clear();
+            if (m_Options.handleClasses)
+                HandleClass(ctUnion);
+            else
+                SkipToOneOfChars(ParserConsts::semicolonclbrace, true);
         }
 #if 1
         else if (token==ParserConsts::kw_operator)
@@ -834,7 +844,9 @@
     if (!newToken && !m_Options.isTemp)
         newToken = TokenExists(name, m_pLastParent, kind);
 
-    if (newToken && newToken->m_TokenKind == kind && newToken->m_Args == args)
+
+    wxString newTokenArgs = (newToken) ? (newToken->m_Args) : _T("");
+    if (newToken && newToken->m_TokenKind == kind && newTokenArgs == args)
     {
         m_pTokens->m_modified = true;
     }
@@ -978,14 +990,30 @@
     // BLAH_BLAH
     if (!token.IsEmpty())
     {
-        // skip the rest of the #define
-        wxString defVal = token + m_Tokenizer.ReadToEOL();
-
+                // skip the rest of the #define
+       wxString defVal = token + m_Tokenizer.ReadToEOL();
+        wxString para(_T(""));
+        size_t start = defVal.find('(');
+        size_t end = defVal.find(')');
+        //Manager::Get()->GetLogManager()->DebugLog(F(_T("Saving nesting level: %d,%d"), start, end));
         // make sure preprocessor definitions are not going under namespaces or classes!
+        if (start != wxString::npos && end != wxString::npos)
+        {
+            para = defVal.Mid(start, end-start+1);
+            m_Str = defVal.Mid(end + 1);
+            m_Str.Trim(false);
+        }
+        else
+        {
+            m_Str = defVal.substr(token.length());
+            m_Str.Trim(false);
+            //defVal = _T("");
+        }
         Token* oldParent = m_pLastParent;
         m_pLastParent = 0L;
-        DoAddToken(tkPreprocessor, token, lineNr, lineNr, m_Tokenizer.GetLineNumber(), defVal, false, true);
+        DoAddToken(tkPreprocessor, token, lineNr, lineNr, m_Tokenizer.GetLineNumber(), para, false, true);
         m_pLastParent = oldParent;
+        m_Str.Clear();
     }
 }
 
@@ -1105,8 +1133,30 @@
     }
 }
 
-void ParserThread::HandleClass(bool isClass)
+void ParserThread::ReadVarNames()
 {
+    while (1)
+    {
+        wxString current = m_Tokenizer.GetToken();
+
+        if (current.IsEmpty())
+            break;
+        if (current==ParserConsts::comma)
+            continue;
+        else if (current==ParserConsts::semicolon)
+            break;
+        else if (wxIsalpha(current.GetChar(0)))
+        {
+//            Manager::Get()->GetLogManager()->DebugLog(F(_T("Adding variable '%s' as '%s' to '%s'"), current.c_str(), m_Str.c_str(), (m_pLastParent?m_pLastParent->m_Name.c_str():_T("<no-parent>"))));
+            DoAddToken(tkVariable, current, m_Tokenizer.GetLineNumber());
+        }
+        else // unexpected
+            break;
+    }
+}
+
+void ParserThread::HandleClass(EClassType ct)
+{
     // need to force the tokenizer _not_ skip anything
     // as we 're manually parsing class decls
     // don't forget to reset that if you add any early exit condition!
@@ -1190,30 +1240,50 @@
 //                Manager::Get()->GetLogManager()->DebugLog(F(_T("Ancestors: ") + ancestors));
             }
 
-            if (current==ParserConsts::opbrace) // unnamed class/struct
+            if (current==ParserConsts::opbrace) // unnamed class/struct/union
             {
                 static size_t num = 0;
                 wxString unnamedTmp;
-                unnamedTmp.Printf(_T("Unnamed-%s-%d"), isClass ? _T("Class") : _T("Struct"), num++);
+                unnamedTmp.Printf(_T("Unnamed%s%d"),
+                                  ct == ctClass ? _T("Class") :
+                                  ct == ctUnion ? _T("Union") :
+                                                  _T("Struct"), num++);
 
                 Token* newToken = DoAddToken(tkClass, unnamedTmp, lineNr);
 
                 Token* lastParent = m_pLastParent;
                 TokenScope lastScope = m_LastScope;
+                bool parsingTypedef = m_ParsingTypedef;
 
                 m_pLastParent = newToken;
-                // default scope is: private for classes, public for structs
-                m_LastScope = isClass ? tsPrivate : tsPublic;
+                // default scope is: private for classes, public for structs, public for unions
+                m_LastScope = ct == ctClass ? tsPrivate : tsPublic;
+                m_ParsingTypedef = false;
 
                 DoParse();
 
+                m_ParsingTypedef = parsingTypedef;
                 m_pLastParent = lastParent;
                 m_LastScope = lastScope;
 
                 m_LastUnnamedTokenName = unnamedTmp; // used for typedef'ing anonymous class/struct/union
 
-                // we should now be right after the closing brace: read the var name
-                break;
+                // we should now be right after the closing brace
+                // no vars are defined on a typedef, only types
+                // In the former example, aa is not part of the typedef.
+                if (m_ParsingTypedef)
+                {
+                    m_Str.Clear();
+                    ReadClsNames(newToken->m_Name);
+                    break;
+                }
+                else
+                {
+                    m_Str = newToken->m_Name;
+                    ReadVarNames();
+                    m_Str.Clear();
+                    break;
+                }
             }
             else if (next==ParserConsts::opbrace)
             {
@@ -1230,17 +1300,35 @@
 
                 Token* lastParent = m_pLastParent;
                 TokenScope lastScope = m_LastScope;
+                bool parsingTypedef = m_ParsingTypedef;
 
                 m_pLastParent = newToken;
-                // default scope is: private for classes, public for structs
-                m_LastScope = isClass ? tsPrivate : tsPublic;
+                // default scope is: private for classes, public for structs, public for unions
+                m_LastScope = ct == ctClass ? tsPrivate : tsPublic;
+                m_ParsingTypedef = false;
 
                 DoParse();
 
+                m_ParsingTypedef = parsingTypedef;
                 m_pLastParent = lastParent;
                 m_LastScope = lastScope;
-                m_LastUnnamedTokenName = current;
-                break;
+
+                // we should now be right after the closing brace
+                // no vars are defined on a typedef, only types
+                // In the former example, aa is not part of the typedef.
+                if (m_ParsingTypedef)
+                {
+                    m_Str.Clear();
+                    ReadClsNames(newToken->m_Name);
+                    break;
+                }
+                else
+                {
+                    m_Str = newToken->m_Name;
+                    ReadVarNames();
+                    m_Str.Clear();
+                    break;
+                }
             }
             else if (next==ParserConsts::semicolon) // forward decl; we don't care
                 break;
@@ -1249,6 +1337,44 @@
                 HandleFunction(current);
                 break;
             }
+            else if (next.GetChar(0) != '*')
+            {
+                // might be instantiation, see the following
+                /*
+                struct HiddenStruct {
+                    int val;
+                };
+
+                struct HiddenStruct yy;
+                */
+                if (TokenExists(current, m_pLastParent, tkClass))
+                {
+                    if (!TokenExists(next, m_pLastParent, tkVariable) )
+                    {
+                        wxString farnext;
+
+                        m_Tokenizer.GetToken(); // go ahead of identifier
+                        farnext = m_Tokenizer.PeekToken();
+
+                        if (farnext==ParserConsts::semicolon)
+                        {
+                            if (m_Options.handleVars)
+                            {
+                                m_Str = current;
+                                DoAddToken(tkVariable, next, m_Tokenizer.GetLineNumber());
+                                m_Str.Clear();
+                            }
+
+                            m_Tokenizer.GetToken(); // eat semi-colon
+                            break;
+                        }
+                        else
+                            m_Tokenizer.UngetToken(); // restore the identifier
+                    }
+                }
+            }
+            else
+            m_Tokenizer.GetToken();
         }
         else
             break;
@@ -1364,7 +1490,7 @@
         if (m_ParsingTypedef)
         {
             static size_t num = 0;
-            token.Printf(_T("Unnamed-Enum-%d"), num++);
+            token.Printf(_T("UnnamedEnum%d"), num++);
             m_LastUnnamedTokenName = token;
         }
         else
@@ -1378,7 +1504,31 @@
     if (wxIsalpha(token.GetChar(0)) || token.GetChar(0) == '_')
     {
         if (m_Tokenizer.PeekToken().GetChar(0) != '{')
+        {
+            if (TokenExists(token, m_pLastParent, tkEnum))
+            {
+                if (!TokenExists(m_Tokenizer.PeekToken(), m_pLastParent, tkVariable) )
+                {
+                    wxString ident = m_Tokenizer.GetToken(); // go ahead of identifier
+
+                    if (m_Tokenizer.PeekToken()==ParserConsts::semicolon)
+                    {
+                        if (m_Options.handleEnums)
+                        {
+                            m_Str = token;
+                            DoAddToken(tkVariable, ident, m_Tokenizer.GetLineNumber());
+                            m_Str.Clear();
+                        }
+
+                        m_Tokenizer.GetToken(); // eat semi-colon
+                    }
+                    else
+                        m_Tokenizer.UngetToken(); // restore the identifier
+                }
+            }
+
             return;
+        }
 
         if (isUnnamed && !m_ParsingTypedef)
         {
@@ -1472,21 +1622,26 @@
         if (token.IsEmpty() || token == ParserConsts::semicolon)
             break;
 
+#if 0
         if (token == ParserConsts::kw_union)
         {
             // "typedef union" is not supported
             SkipToOneOfChars(ParserConsts::semicolon, true);
             break;
         }
-
-        else if (token == ParserConsts::kw_class ||
-            token == ParserConsts::kw_struct)
+        else
+#endif
+        if (   token == ParserConsts::kw_class
+            || token == ParserConsts::kw_struct
+            || token == ParserConsts::kw_union)
         {
-            // "typedef struct|class"
+            // "typedef struct|class|union"
 #if PARSER_DEBUG_OUTPUT
             Manager::Get()->GetLogManager()->DebugLog(F(_("Before HandleClass m_LastUnnamedTokenName='%s'"), m_LastUnnamedTokenName.c_str()));
 #endif
-            HandleClass(token == ParserConsts::kw_class);
+            HandleClass(token == ParserConsts::kw_class ? ctClass :
+                        token == ParserConsts::kw_union ? ctUnion :
+                                                          ctStructure);
             token = m_LastUnnamedTokenName;
 #if PARSER_DEBUG_OUTPUT
             Manager::Get()->GetLogManager()->DebugLog(F(_("After HandleClass m_LastUnnamedTokenName='%s'"), m_LastUnnamedTokenName.c_str()));
@@ -1582,15 +1737,60 @@
 #if PARSER_DEBUG_OUTPUT
     Manager::Get()->GetLogManager()->DebugLog(F(_("Adding typedef: name='%s', ancestor='%s'"), components.front().c_str(), ancestor.c_str()));
 #endif
-    Token* tdef = DoAddToken(tkTypedef, components.front(), lineNr, 0, 0, args);
+//    wxString str = components.front();
+ //   Token* tdef = DoAddToken(tkClass, components.front(), lineNr, 0, 0, args);
+Token* tdef = DoAddToken(tkTypedef, components.front(), lineNr, 0, 0, args);
+//if ( m_Filename == _T("F:\\fortest\\main.cpp"))
+//    Manager::Get()->GetLogManager()->DebugLog(ancestor);
     if (tdef)
     {
         if (!is_function_pointer)
         {
             tdef->m_AncestorsString = ancestor;
+
             tdef->m_ActualType = ancestor;
+//            if ( m_Filename == _T("F:\\fortest\\main.cpp"))
+//            {
+//                Manager::Get()->GetLogManager()->DebugLog(tdef->m_Name + _T("  ") + tdef->m_AncestorsString + tdef->m_ActualType);
+//            }
         }
         else
+        {
             tdef->m_ActualType = ancestor + args;
+//            tdef->m_AncestorsString = str;
+        }
     }
 }
+void ParserThread::ReadClsNames(wxString& ancestor)
+{
+    while (1)
+    {
+        wxString current = m_Tokenizer.GetToken();
+
+        if (current.IsEmpty())
+            break;
+        if (current==ParserConsts::comma)
+            continue;
+        else if (current==ParserConsts::semicolon)
+        {
+            m_Tokenizer.UngetToken();
+            break;
+        }
+
+        else if (wxIsalpha(current.GetChar(0)))
+        {
+//            Manager::Get()->GetLogManager()->DebugLog(F(_T("Adding variable '%s' as '%s' to '%s'"), current.c_str(), m_Str.c_str(), (m_pLastParent?m_pLastParent->m_Name.c_str():_T("<no-parent>"))));
+            Token* newToken = DoAddToken(tkClass, current, m_Tokenizer.GetLineNumber());
+            if (!newToken)
+                break;
+            else
+            {
+                wxString tempAncestor = ancestor;
+                newToken->m_AncestorsString = tempAncestor;
+            }
+
+        }
+        else // unexpected
+            break;
+    }
+}
Index: parserthread.h
===================================================================
--- parserthread.h (revision 5730)
+++ parserthread.h (working copy)
@@ -79,6 +79,7 @@
         virtual void SetTokens(TokensTree* tokens);
         const wxString& GetFilename() const { return m_Filename; }
     protected:
+        enum EClassType { ctStructure = 0, ctClass = 1, ctUnion = 3 };
         wxChar SkipToOneOfChars(const wxString& chars, bool supportNesting = false);
         void DoParse();
         void SkipBlock();
@@ -87,7 +88,9 @@
         void HandleDefines();
         void HandlePreprocessorBlocks(const wxString& preproc);
         void HandleNamespace();
-        void HandleClass(bool isClass = true);
+        void ReadVarNames();
+        void ReadClsNames(wxString& ancestor);
+        void HandleClass(EClassType ct);
         void HandleFunction(const wxString& name, bool isOperator = false);
         void HandleEnum();
         void HandleTypedef();

--- End code ---

daniloz:
Sorry, I forgot to mention that I'm indeed using cc-trunk compiled by myself (i.e., r5730).

Which cc-branch do you refer to? In http://svn.berlios.de/svnroot/repos/codeblocks/branches/, I see several dirs... Is it codecompletion_refactoring ???

MortenMacFly:

--- Quote from: daniloz on August 13, 2009, 08:25:36 am ---Is it codecompletion_refactoring ???

--- End quote ---
Yes.

daniloz:
Ok, even after getting the cc-branch and compiling it, it's still not working here... Am I missing something?

Navigation

[0] Message Index

[#] Next page

Go to full version