Patch #3345 2012-10-06 15:35
koonschi
Added code completion of declarations in for/if/while heads- Download
 - 3345-Added_code_com.patch (9.3 KB)
 
Index: plugins/codecompletion/parser/parserthread.cpp
===================================================================
--- plugins/codecompletion/parser/parserthread.cpp    (revision 8431)
+++ plugins/codecompletion/parser/parserthread.cpp    (working copy)
@@ -666,7 +666,8 @@
                 if (!m_Options.useBuffer || m_Options.bufferSkipBlocks)
                     SkipToOneOfChars(ParserConsts::semicolonclbrace, true, true);
                 else
-                    m_Tokenizer.GetToken(); // skip arguments
+                    HandleConditionalArguments();
+
                 m_Str.Clear();
             }
             else
@@ -682,7 +683,8 @@
                 if (!m_Options.useBuffer || m_Options.bufferSkipBlocks)
                     SkipToOneOfChars(ParserConsts::semicolonclbrace, true, true);
                 else
-                    m_Tokenizer.GetToken(); // skip arguments
+                    HandleForLoopArguments();
+
                 m_Str.Clear();
             }
             else
@@ -727,7 +729,8 @@
                 if (!m_Options.useBuffer || m_Options.bufferSkipBlocks)
                     SkipToOneOfChars(ParserConsts::semicolonclbrace, true, true);
                 else
-                    m_Tokenizer.GetToken(); // skip arguments
+                    HandleConditionalArguments();
+
                 m_Str.Clear();
             }
             else if (token == ParserConsts::kw_const)
@@ -2070,6 +2073,188 @@
     }
 }
 
+void ParserThread::HandleConditionalArguments()
+{
+    // if these aren't empty at this point, we have a syntax error
+    if (!m_Str.empty())
+        return;
+
+    if (!m_PointerOrRef.empty())
+        return;
+
+    if (!m_TemplateArgument.empty())
+        return;
+
+    // conditional arguments can look like this:
+    // (int i = 12)
+    // (Foo *bar = getFooBar())
+    // (var <= 12 && (getType() != 23))
+    wxString args = m_Tokenizer.GetToken();
+
+    // remove braces
+    if (args.StartsWith(_T("(")))
+        args = args.Mid(1, args.length() - 1);
+
+    if (args.EndsWith(_T(")")))
+        args = args.Mid(0, args.length() - 1);
+
+    // parse small tokens inside for loop head
+    TokenTree tree;
+    wxString fileName = m_Tokenizer.GetFilename();
+    Tokenizer smallTokenizer(&tree);
+
+    smallTokenizer.InitFromBuffer(args, fileName, m_Tokenizer.GetLineNumber());
+
+    while (IS_ALIVE)
+    {
+        wxString token = smallTokenizer.GetToken();
+        if (token.empty())
+            break;
+
+        wxString peek = smallTokenizer.PeekToken();
+
+        if (peek.empty())
+        {
+            if (!m_Str.empty())
+            {
+                // remove template argument if there is one
+                wxString varType, templateArgs;
+                RemoveTemplateArgs(m_Str, varType, templateArgs);
+
+                m_Str = varType;
+                m_TemplateArgument = templateArgs;
+
+                Token *newToken = DoAddToken(tkVariable, token, smallTokenizer.GetLineNumber());
+                if (newToken && !m_TemplateArgument.IsEmpty())
+                {
+                    ResolveTemplateArgs(newToken);
+                }
+                else
+                {
+                    TRACE(_T("HandleConditionalArguments() : Unable to create/add new token: ") + token);
+                }
+            }
+
+            break;
+        }
+        else
+        {
+            if (token == ParserConsts::ref_chr || token == ParserConsts::ptr_chr)
+            {
+                m_PointerOrRef << token;
+            }
+            else
+            {
+                if (!m_Str.empty())
+                    m_Str << _T(" ");
+
+                m_Str << token;
+            }
+        }
+    }
+
+    m_Str.clear();
+    m_PointerOrRef.clear();
+    m_TemplateArgument.clear();
+}
+
+void ParserThread::HandleForLoopArguments()
+{
+    // if these aren't empty at this point, we have a syntax error
+    if (!m_Str.empty())
+        return;
+
+    if (!m_PointerOrRef.empty())
+        return;
+
+    if (!m_TemplateArgument.empty())
+        return;
+
+    // for loop heads look like this:
+    // ([init1 [, init2 ...] ] ; [cond1 [, cond2 ..]]; [mod1 [, mod2 ..]])
+    wxString args = m_Tokenizer.GetToken();
+
+    // remove braces
+    if (args.StartsWith(_T("(")))
+        args = args.Mid(1, args.length() - 1);
+    if (args.EndsWith(_T(")")))
+        args = args.Mid(0, args.length() - 1);
+
+    // parse small tokens inside for loop head
+    TokenTree tree;
+    wxString fileName = m_Tokenizer.GetFilename();
+    Tokenizer smallTokenizer(&tree);
+
+    smallTokenizer.InitFromBuffer(args, fileName, m_Tokenizer.GetLineNumber());
+
+    while (IS_ALIVE)
+    {
+        wxString token = smallTokenizer.GetToken();
+        if (token.empty())
+            break;
+
+        wxString peek = smallTokenizer.PeekToken();
+
+        bool createNewToken = false;
+        bool finished = false;
+
+        if (peek == ParserConsts::comma)
+        {
+
download for full patch...
History
koonschi 2012-10-06 15:40
        Added some whitespaces to meet the coding conventions
koonschi 2012-10-07 10:36
        Templated declarations are now recognized correctly
koonschi 2012-10-07 10:45
        Removed tabs and replaced them with whitespaces
koonschi 2012-10-09 09:59
        Comments corrected
ollydbg 2012-10-10 09:50
        Looks good to me, but I need more time to test it.
mortenmacfly 2012-12-16 14:48
        ...just for the record, testing, too (for some weeks now) - no issues so far.
ollydbg 2012-12-21 07:41
        Applied in the trunk rev 8700. Thanks.