Author Topic: Code Completion problem with some wx classes  (Read 5354 times)

Offline Quiss

  • Multiple posting newcomer
  • *
  • Posts: 76
Code Completion problem with some wx classes
« on: April 07, 2015, 09:33:50 am »
Hi,
Code completion is not working with some classes; wxDataViewCtrl, wxDataViewTreeCtrl, wxDataViewListCtrl and wxDataViewItem are the ones i've checked. The project builds and runs ok by the way. I can see and select,  for example m_dataViewCtrl1 but when i enter -> nothing shows up. I tried some other classes like wxDataViewModel and wxPropertyGrid, code completion works fine with them.

I create a new wxWidgets project from the wizard, choose wxWidgets 3.0.x, wxFormBuilder Frame Based, wxWidgets location $(#wx30), all selected in wxWidgets library settings and none selected in Miscellanous settings.

Upon opening WxWizFrame.fbp in wxFormBuilder, it warns about making some changes in code regarding the new version and i need to add #include <wx/msgdlg.h> to header in order to build correctly.

Code::Blocks svn 10091
Windows 8.1
tdm64-gcc-4.7.1-3
wxWidgets-3.0.2 (build configuration: MONOLITHIC=1 SHARED=1 UNICODE=1 BUILD=debug and release)
wxFormBuilder v3.5

Online ollydbg

  • Developer
  • Lives here!
  • *****
  • Posts: 5915
  • OpenCV and Robotics
    • Chinese OpenCV forum moderator
Re: Code Completion problem with some wx classes
« Reply #1 on: April 08, 2015, 03:16:25 pm »
Hi, I did a quick test, and I found that the parser can't parse the file "wxWidgets-3.0.0\include\wx\dataview.h" correctly. It just skip some code in the middle of the parsing. Please report it to our SoureForge page, so that this bug won't lost in our forum. Thank you!
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 Quiss

  • Multiple posting newcomer
  • *
  • Posts: 76
Re: Code Completion problem with some wx classes
« Reply #2 on: April 09, 2015, 07:37:18 am »
Hi ollydbg,

I've just opened a ticket: https://sourceforge.net/p/codeblocks/tickets/154/

Online ollydbg

  • Developer
  • Lives here!
  • *****
  • Posts: 5915
  • OpenCV and Robotics
    • Chinese OpenCV forum moderator
Re: Code Completion problem with some wx classes
« Reply #3 on: April 11, 2015, 02:52:32 pm »
I just create a very simple test case from the "wxWidgets-3.0.0\include\wx\dataview.h" , which failed in our CCTest.
Code: cpp
// bit masks for the various column attributes
enum
{
    // column can be resized (included in default flags)
    wxCOL_RESIZABLE   = 1,

    // column can be clicked to toggle the sort order by its contents
    wxCOL_SORTABLE    = 2,

    // column can be dragged to change its order (included in default)
    wxCOL_REORDERABLE = 4,

    // column is not shown at all
    wxCOL_HIDDEN      = 8,

    // default flags for wxHeaderColumn ctor
    wxCOL_DEFAULT_FLAGS = wxCOL_RESIZABLE | wxCOL_REORDERABLE
};


// for compatibility only, do not use
enum wxDataViewColumnFlags
{
    wxDATAVIEW_COL_RESIZABLE     = wxCOL_RESIZABLE,
    wxDATAVIEW_COL_SORTABLE      = wxCOL_SORTABLE,
    wxDATAVIEW_COL_REORDERABLE   = wxCOL_REORDERABLE,
    wxDATAVIEW_COL_HIDDEN        = wxCOL_HIDDEN
};

class AAA
{
    int m_aaa;
};

AAA b;

//b.//m_aaa

Note: I believe our parser failed on the line "wxDATAVIEW_COL_HIDDEN        = wxCOL_HIDDEN".

Edit: Changes to C++ code style.
« Last Edit: April 11, 2015, 02:57:16 pm by MortenMacFly »
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.

Online ollydbg

  • Developer
  • Lives here!
  • *****
  • Posts: 5915
  • OpenCV and Robotics
    • Chinese OpenCV forum moderator
Re: Code Completion problem with some wx classes
« Reply #4 on: April 11, 2015, 04:06:18 pm »
I debugged a while, and I found that the bug is introduced in r9642.
The reason is that:
Code: cpp
enum wxDataViewColumnFlags
{
    wxDATAVIEW_COL_RESIZABLE     = wxCOL_RESIZABLE,
    wxDATAVIEW_COL_SORTABLE      = wxCOL_SORTABLE,
    wxDATAVIEW_COL_REORDERABLE   = wxCOL_REORDERABLE,
    wxDATAVIEW_COL_HIDDEN        = wxCOL_HIDDEN
};
Note that wxCOL_HIDDEN is not a member token of the wxDataViewColumnFlags, so the below code goes to the else clause.
Code: cpp
bool ParserThread::CalcEnumExpression(Token* tokenParent, long& result, wxString& peek)
{
    // need to force the tokenizer skip raw expression
    const TokenizerState oldState = m_Tokenizer.GetState();
    // expand macros, but don't read a single parentheses
    m_Tokenizer.SetState(tsRawExpression);

    Expression exp;
    wxString token, next;

    while (IS_ALIVE)
    {
        token = m_Tokenizer.GetToken();
        if (token.IsEmpty())
            return false;
        if (token == _T("\\"))
            continue;
        if (token == ParserConsts::comma || token == ParserConsts::clbrace)
        {
            m_Tokenizer.UngetToken();
            peek = token;
            break;
        }
        if (token == ParserConsts::dcolon)
        {
            peek = SkipToOneOfChars(ParserConsts::commaclbrace);
            exp.Clear();
            break;
        }

        if (wxIsalpha(token[0]) || token[0] == ParserConsts::underscore_chr) // handle enum or macro
        {
            const Token* tk = m_TokenTree->at(m_TokenTree->TokenExists(token, tokenParent->m_Index, tkEnumerator));

            if (tk) // the enumerator token
            {
                if (!tk->m_Args.IsEmpty() && wxIsdigit(tk->m_Args[0]))
                    token = tk->m_Args; // add the value to exp
            }
            else
            {
                peek = SkipToOneOfChars(ParserConsts::commaclbrace);
                exp.Clear();
                break;
            }
        }
I just debugged into the function SkipToOneOfChars(ParserConsts::commaclbrace), I see that the "}" is already eat in this function. When up to the caller "void ParserThread::HandleEnum()", we will eat another token after "}", and finally the code after that will be eat, and the body of class AAA is totally skipped.
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 Huki

  • Multiple posting newcomer
  • *
  • Posts: 95
Re: Code Completion problem with some wx classes
« Reply #5 on: April 11, 2015, 08:08:21 pm »
I just debugged into the function SkipToOneOfChars(ParserConsts::commaclbrace), I see that the "}" is already eat in this function. When up to the caller "void ParserThread::HandleEnum()", we will eat another token after "}", and finally the code after that will be eat, and the body of class AAA is totally skipped.
Yes, we can see from:
Code: cpp
        if (token == ParserConsts::comma || token == ParserConsts::clbrace)
        {
            m_Tokenizer.UngetToken();
            peek = token;
            break;
        }
that UngetToken() is used if we already skipped comma or clbrace. We can do the same thing after SkipToOneOfChars().
This patch should fix it:
Code: diff
diff --git a/src/plugins/codecompletion/parser/parserthread.cpp b/src/plugins/codecompletion/parser/parserthread.cpp
index d882063..d35010c 100644
--- a/src/plugins/codecompletion/parser/parserthread.cpp
+++ b/src/plugins/codecompletion/parser/parserthread.cpp
@@ -2655,6 +2655,7 @@ bool ParserThread::CalcEnumExpression(Token* tokenParent, long& result, wxString
         if (token == ParserConsts::dcolon)
         {
             peek = SkipToOneOfChars(ParserConsts::commaclbrace);
+            m_Tokenizer.UngetToken();
             exp.Clear();
             break;
         }
@@ -2671,6 +2672,7 @@ bool ParserThread::CalcEnumExpression(Token* tokenParent, long& result, wxString
             else
             {
                 peek = SkipToOneOfChars(ParserConsts::commaclbrace);
+                m_Tokenizer.UngetToken();
                 exp.Clear();
                 break;
             }

Edit: Applied syntax highlighting for diff.
« Last Edit: April 12, 2015, 11:29:27 am by MortenMacFly »

Online ollydbg

  • Developer
  • Lives here!
  • *****
  • Posts: 5915
  • OpenCV and Robotics
    • Chinese OpenCV forum moderator
Re: Code Completion problem with some wx classes
« Reply #6 on: April 12, 2015, 06:58:42 am »
I just debugged into the function SkipToOneOfChars(ParserConsts::commaclbrace), I see that the "}" is already eat in this function. When up to the caller "void ParserThread::HandleEnum()", we will eat another token after "}", and finally the code after that will be eat, and the body of class AAA is totally skipped.
Yes, we can see from:
Code: cpp
        if (token == ParserConsts::comma || token == ParserConsts::clbrace)
        {
            m_Tokenizer.UngetToken();
            peek = token;
            break;
        }
that UngetToken() is used if we already skipped comma or clbrace. We can do the same thing after SkipToOneOfChars().
This patch should fix it:
...
Yes, it fix the bug, thanks. Also the Op's issue is fixed by this patch.

My idea is that: is it better to check some thing in this code:
Code: cpp
        if (peek == ParserConsts::comma || peek == ParserConsts::clbrace)
        {
            // this "if", avoids non-valid enumerators
            // like a comma (if no enumerators follow)
            if (   wxIsalpha(token.GetChar(0))
                || (token.GetChar(0) == ParserConsts::underscore_chr) )
            {
                wxString args;
                if (updateValue)
                    args << enumValue++;

                Token* lastParent = m_LastParent;
                m_LastParent = newEnum;
                Token* enumerator = DoAddToken(tkEnumerator, token, m_Tokenizer.GetLineNumber(), 0, 0, args);
                enumerator->m_Scope = isEnumClass ? tsPrivate : tsPublic;
                m_LastParent = lastParent;
            }
            // add check here
            // if (peek == ParserConsts::clbrace)
            // break?
        }
I don't test it yet, but just read and modify the source code.
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: 9694
Re: Code Completion problem with some wx classes
« Reply #7 on: April 12, 2015, 11:30:19 am »
...minor off-topic note: You can also enable syntax highlighting for patches (diff) using the "diff" code tag extension instead of cpp or text. (I believe there are roughly 200 formats supported... so chances are good we have one for our needs.)

I've edited Hukis post accordingly.
Compiler logging: Settings->Compiler & Debugger->tab "Other"->Compiler logging="Full command line"
C::B Manual: https://www.codeblocks.org/docs/main_codeblocks_en.html
C::B FAQ: https://wiki.codeblocks.org/index.php?title=FAQ

Offline Quiss

  • Multiple posting newcomer
  • *
  • Posts: 76
Re: Code Completion problem with some wx classes
« Reply #8 on: April 14, 2015, 07:02:26 am »
I've build r10218 in trunk and it works like a charm. Thanks for your efforts.