Code::Blocks Forums

Developer forums (C::B DEVELOPMENT STRICTLY!) => Development => CodeCompletion redesign => Topic started by: nanyu on December 13, 2009, 01:51:37 AM

Title: CC fail after A class's static method called.
Post by: nanyu on December 13, 2009, 01:51:37 AM

#include <iostream>

using namespace std;

class A
{
public:
    static void Test()
    {
    }
};

struct Soo
{
    int a;
};

Soo globalSoo;

int main()
{
    A::Test(); //remove this line, then cc work well.

    globalSoo.a = 9; //cc  allways do work well here

    Soo localeSoo;

    localeSoo.   // <-- cc do nothing

    return 0;
}


CC didn't work after I input "localSoo.".
After remove the line "A::Test()",  cc work well when I input  "localeSoo."

//////////////
Windows XP
Code::Blocks svn5911
Title: Re: CC fail after A class's static method called.
Post by: blueshake on December 13, 2009, 03:08:31 AM
yes,you are right.you also can move the statement Soo localeSoo; to the top of A::Test(); since the A:: will affect the scope of localeSoo
Title: Re: CC fail after A class's static method called.
Post by: nanyu on December 13, 2009, 03:24:49 AM
Quote from: blueshake on December 13, 2009, 03:08:31 AM
yes,you are right.you also can move the statement Soo localeSoo; to the top of A::Test(); since the A:: will affect the scope of localeSoo

Is it a bug of CC?
Title: Re: CC fail after A class's static method called.
Post by: blueshake on December 13, 2009, 11:01:52 AM
Seem
Quote from: nanyu on December 13, 2009, 03:24:49 AM
Quote from: blueshake on December 13, 2009, 03:08:31 AM
yes,you are right.you also can move the statement Soo localeSoo; to the top of A::Test(); since the A:: will affect the scope of localeSoo

Is it a bug of CC?

Seem so.no time to check into it.
Title: Re: CC fail after A class's static method called.
Post by: nanyu on December 13, 2009, 02:05:33 PM
I do the same thing in CodeLite, everything ok.  :(
Title: Re: CC fail after A class's static method called.
Post by: MortenMacFly on December 14, 2009, 03:07:07 PM
Cannot reproduce with trunk. Please try the testing workspace, namely the project "function_decls". There is such a class inside with a static member function, as well as a global struct. I see all: The static (class) method, the methods after that as well as the struct and it's member variable.

So...?!
Title: Re: CC fail after A class's static method called.
Post by: MortenMacFly on December 14, 2009, 03:09:57 PM
...even with the test case provided here: Works just fine... (see attached image)?!

[attachment deleted by admin]
Title: Re: CC fail after A class's static method called.
Post by: oBFusCATed on December 14, 2009, 04:28:31 PM
You're missing the

    A::Test(); //remove this line, then cc work well.

line
Title: Re: CC fail after A class's static method called.
Post by: Jenna on December 14, 2009, 04:57:42 PM
Doesn't work for me either (trunk), it also does not work if I have std::cout before the declaration of localeSoo, std::endl doesn't matter.
Title: Re: CC fail after A class's static method called.
Post by: MortenMacFly on December 14, 2009, 05:51:47 PM
Quote from: oBFusCATed on December 14, 2009, 04:28:31 PM
You're missing the

    A::Test(); //remove this line, then cc work well.

line
Quote from: jens on December 14, 2009, 04:57:42 PM
Doesn't work for me either (trunk), it also does not work if I have std::cout before the declaration of localeSoo, std::endl doesn't matter.
I did that, it still works (see image attached). Could you please try to reproduce with CC from trunk, and the testing project from trunk?

[attachment deleted by admin]
Title: Re: CC fail after A class's static method called.
Post by: oBFusCATed on December 14, 2009, 05:54:06 PM
I'm not telling you that I've reproduced it :)
I've just spotted this accidentally.
Title: Re: CC fail after A class's static method called.
Post by: Jenna on December 14, 2009, 06:12:56 PM
Quote from: MortenMacFly on December 14, 2009, 05:51:47 PM
Quote from: oBFusCATed on December 14, 2009, 04:28:31 PM
You're missing the

    A::Test(); //remove this line, then cc work well.

line
Quote from: jens on December 14, 2009, 04:57:42 PM
Doesn't work for me either (trunk), it also does not work if I have std::cout before the declaration of localeSoo, std::endl doesn't matter.
I did that, it still works (see image attached). Could you please try to reproduce with CC from trunk, and the testing project from trunk?
Quote from: jens on December 14, 2009, 04:57:42 PM
Doesn't work for me either (trunk), it also does not work if I have std::cout before the declaration of localeSoo, std::endl doesn't matter.

Title: Re: CC fail after A class's static method called.
Post by: MortenMacFly on December 14, 2009, 07:53:14 PM
Quote from: jens on December 14, 2009, 06:12:56 PM
Quote from: jens on December 14, 2009, 04:57:42 PM
Doesn't work for me either (trunk), it also does not work if I have std::cout before the declaration of localeSoo, std::endl doesn't matter.
I realised that but thought it's a mistake because putting std::cout before the definition of the global variable (struct) results in invalid code. I mean: It's outside any function / method then...?!

Could yu just post what exactly I have to put into my main file to reproduce? Surely it should be valid code somehow.... otherwise I see no value in adding support to CC for parsing invalid code. :shock:
Title: Re: CC fail after A class's static method called.
Post by: Jenna on December 14, 2009, 08:02:18 PM
Quote from: MortenMacFly on December 14, 2009, 07:53:14 PM
Quote from: jens on December 14, 2009, 06:12:56 PM
Quote from: jens on December 14, 2009, 04:57:42 PM
Doesn't work for me either (trunk), it also does not work if I have std::cout before the declaration of localeSoo, std::endl doesn't matter.
I realised that but thought it's a mistake because putting std::cout before the definition of the global variable (struct) results in invalid code. I mean: It's outside any function / method then...?!

Could yu just post what exactly I have to put into my main file to reproduce? Surely it should be valid code somehow.... otherwise I see no value in adding support to CC for parsing invalid code. :shock:

I took nanyu's example from the first post (http://forums.next.codeblocks.org/index.php/topic,11677.msg79385.html#msg79385).
localeSoo is a locale variable, that means it's perfectly legal to have std::cout before it.

There's no problem with global variables, but with variables, that are declared locally after the use of std::cout or the use of the static class method A::Test().
Title: Re: CC fail after A class's static method called.
Post by: blueshake on December 15, 2009, 02:38:09 AM
hi,guys
it is a bug as I knew.
you can see the debug log if turn the debugSmartSense on.
and you will find that the variable scope of localeSoo are different with/without statement A::Test();

with:
QuoteFindAIMatches() Looping 1 results
FindAIMatches() Match: 'localeSoo' (30032) : 'A::Soo'
BreakUpComponents() Breaking up 'A::Soo'
BreakUpComponents() Found component: 'A' (Namespace)
BreakUpComponents() Found component: 'Soo' (SearchText)
FindAIMatches() Looking for type: 'A::Soo' (2 components)
FindAIMatches() Now looking under 'Global namespace'
FindAIMatches() ----- FindAIMatches - enter -----

without

QuoteFindAIMatches() Looping 1 results
FindAIMatches() Match: 'localeSoo' (30032) : 'Soo'
BreakUpComponents() Breaking up 'Soo'
BreakUpComponents() Found component: 'Soo' (SearchText)
FindAIMatches() Looking for type: 'Soo' (1 components)
FindAIMatches() Now looking under 'Global namespace'
FindAIMatches() ----- FindAIMatches - enter -----


as I said above, the A:: will affect the scope of localeSoo
Title: Re: CC fail after A class's static method called.
Post by: MortenMacFly on December 15, 2009, 07:09:06 AM
Quote from: jens on December 14, 2009, 08:02:18 PM
I took nanyu's example from the first post (http://forums.next.codeblocks.org/index.php/topic,11677.msg79385.html#msg79385).
Alright... :?
I did not scroll to the end of the text box and always just copied the upper part (excluding the actual main function). My fault. Now that I can reproduce I realised the following while debugging:

With the static method call look what the buffer looks like:
ParseLocalBlock() Block:
oo;

int main()
{
    A::Test(); //remove this line, then cc work well.

    globalSoo.a = 9; //cc  allways do work well here

    Soo localeSoo;

    localeSoo.

Without the static method call it looks like this:
ParseLocalBlock() Block:

    globalSoo.a = 9; //cc  allways do work well here

    Soo localeSoo;

    localeSoo.

...digging into it...
Title: Re: CC fail after A class's static method called.
Post by: MortenMacFly on December 15, 2009, 08:34:22 AM
Quote from: MortenMacFly on December 15, 2009, 07:09:06 AM
...digging into it...
Here is the problem:
GetQueueAsNamespaceString()
returns "A::" which is wrong.
Who implemented this method??? :lol:

I am committing some more debug stuff later today... so you can try yourself once setting PARSERTHREAD_DEBUG_OUTPUT to 1 while compiling.
Title: Re: CC fail after A class's static method called.
Post by: ollydbg on December 15, 2009, 10:18:41 AM
In the function AI().

The "global search scope" should added for every code completion session.

    // always add scope -1 (i.e. global namespace)
    search_scope->insert(-1);

    // find all other matches
    std::queue<ParserComponent> components;
    BreakUpComponents(parser, actual, components);

    m_LastAISearchWasGlobal = components.size() <= 1;
    if (!components.empty())
        m_LastAIGlobalSearch = components.front().component;

    // actually find all matches in selected namespaces
    for (TokenIdxSet::iterator it = search_scope->begin(); it != search_scope->end(); ++it)
    {
        if (s_DebugSmartSense)
        {
            Token* scopeToken = tree->at(*it);
            Manager::Get()->GetLogManager()->DebugLog(F(_T("AI() Parent scope: '%s' (%d)"),
                                                        scopeToken ? scopeToken->m_Name.wx_str() : _T("Global namespace"),
                                                        *it));
        }
        FindAIMatches(parser, components, result, *it, noPartialMatch, caseSensitive, true, 0xffff, search_scope);
    }

//    if(result.size()<1)//find nothing in the search_scope, add global namespace
//    {
//        if (s_DebugSmartSense)
//        {
//            Manager::Get()->GetLogManager()->DebugLog(F(_T("AI() result is zero, so, add the Global namespace")));
//
//        }
//        search_scope->insert(-1);
//        FindAIMatches(parser, components, result, -1, noPartialMatch, caseSensitive, true, 0xffff, search_scope);
//    }


For example



int aaaa;

main(){

int aaaa;

// do code completion here.
}

both the global aaaa and auto variable aaaa should be matched.

Title: Re: CC fail after A class's static method called.
Post by: ollydbg on December 15, 2009, 10:23:51 AM
Here is the test code:


class A
{
public:
   static void Test()
   {
   }
};

struct Soo
{
   int aaaa;
};

Soo globalSoo;

int main()
{
   A::Test(); //remove this line, then cc work well.

   globalSoo.aaaa = 9; //cc  allways do work well here

   Soo localeSoo;

   localeSoo.; // <-- cc do nothing

   return 0;
}


and the log output of auto code completion after entering the "dot" after "localeSoo"


MarkItemsByAI()
ParseUsingNamespace() Parse file scope for "using namespace"
ParseFunctionArguments() Parse function arguments
FindCurrentFunctionStart() Cached namespace='', cached proc='main'
GenerateResultSet() search 'main', parent='Global namespace (id:0, type:(null)), isPrefix=0'
ParseFunctionArguments() + Function match: main
ParseLocalBlock() Parse local block
FindCurrentFunctionStart() Cached namespace='', cached proc='main'
Parse() : parsing
DoParse() : Loop:m_Str='', token='A'
DoParse() : Loop:m_Str='', token='Test'
DoParse() : Loop:m_Str='', token='()'
DoParse() : Loop:m_Str='', token=';'
DoParse() : Loop:m_Str='', token='globalSoo'
DoParse() : Loop:m_Str='globalSoo ', token='.'
DoParse() : Loop:m_Str='', token='Soo'
DoParse() : Loop:m_Str='Soo ', token='localeSoo'
DoAddToken() : Created token='localeSoo', file_idx=0, line=6
GetActualTokenType() : Searching within m_Str='Soo'
GetActualTokenType() : Compensated m_Str='Soo'
GetActualTokenType() : Found 'Soo'
DoAddToken() : Prepending 'A::'
DoAddToken() : Added/updated token 'localeSoo' (6), type 'Soo', actual 'A::Soo'. Parent is  (-1)
DoParse() : Loop:m_Str='Soo', token=';'
DoParse() : Loop:m_Str='', token='localeSoo'
DoParse() : Loop:m_Str='localeSoo ', token='.'
ParseLocalBlock() Block:

   A::Test(); //remove this line, then cc work well.

   globalSoo.aaaa = 9; //cc  allways do work well here

   Soo localeSoo;

   localeSoo.
ParseLocalBlock() Local tokens:
ParseLocalBlock() + Soo localeSoo parent =
AI() AI enter, actual: "    localeSoo."
AI() =========================================================
AI() Doing AI for '    localeSoo.':
FindCurrentFunctionStart() Cached namespace='', cached proc='main'
GenerateResultSet() search 'main', parent='Global namespace (id:0, type:(null)), isPrefix=0'
AI() Adding search namespace: Global namespace
BreakUpComponents() Breaking up '    localeSoo.'
BreakUpComponents() Found component: 'localeSoo' (Class)
BreakUpComponents() Found component: '' (SearchText)
AI() Parent scope: 'Global namespace' (-1)
FindAIMatches() ----- FindAIMatches - enter -----
FindAIMatches() Search for localeSoo, isLast = 0
FindAIMatches() Looping 1 results
FindAIMatches() Match: 'localeSoo' (ID='6') : type='A::Soo'
BreakUpComponents() Breaking up 'A::Soo'
BreakUpComponents() Found component: 'A' (Namespace)
BreakUpComponents() Found component: 'Soo' (SearchText)
FindAIMatches() Looking for type: 'A::Soo' (2 components)
FindAIMatches() Now looking under 'Global namespace'
FindAIMatches() ----- FindAIMatches - enter -----
FindAIMatches() Search for A, isLast = 0
FindAIMatches() Looping 1 results
FindAIMatches() Match: 'A' (ID='5') : type=''
FindAIMatches() ----- FindAIMatches - enter -----
FindAIMatches() Search for Soo, isLast = 1
FindAIMatches() Looping 0 results
FindAIMatches() ----- FindAIMatches - leave -----
FindAIMatches() ----- FindAIMatches - leave -----
FindAIMatches() No types matched 'A::Soo'.
FindAIMatches() ----- FindAIMatches - enter -----
FindAIMatches() Search for , isLast = 1
FindAIMatches() Looping 0 results
FindAIMatches() ----- FindAIMatches - leave -----
FindAIMatches() ----- FindAIMatches - leave -----
AI() AI leave, returned 0 results
0 results




Note:
DoAddToken() : Added/updated token 'localeSoo' (6), type 'Soo', actual 'A::Soo'. Parent is  (-1)

This is totally wrong!! I'm trying to find the error......
Title: Re: CC fail after A class's static method called.
Post by: ollydbg on December 15, 2009, 10:33:21 AM
In the DoParse function.

                else if (peek==ParserConsts::dcolon)
                {
                    if (m_Str.IsEmpty())
                        m_EncounteredTypeNamespaces.push(token); // it's a type's namespace
                    else
                        m_EncounteredNamespaces.push(token);
                    m_Tokenizer.GetToken(); // eat ::
                }


So, for these statement:



    A::Test(); //remove this line, then cc work well.

    globalSoo.aaaa = 9; //cc  allways do work well here

    Soo localeSoo;

    localeSoo.; // <-- cc do nothing



A is pushed as a "typed namespace", this is wrong.

Title: Re: CC fail after A class's static method called.
Post by: ollydbg on December 15, 2009, 10:45:41 AM
This patch can simply fix the bug.

Index: parserthread.cpp
===================================================================
--- parserthread.cpp (revision 5977)
+++ parserthread.cpp (working copy)
@@ -456,6 +456,9 @@
        if (token==ParserConsts::semicolon)
        {
            m_Str.Clear();
+            // clear typed namespace here
+            while (!m_EncounteredTypeNamespaces.empty())
+                m_EncounteredTypeNamespaces.pop();
        }
        else if (token==ParserConsts::kw_delete ||
                (token==ParserConsts::dot) ||



For example:
   A::Test(); //remove this line, then cc work well.

   globalSoo.aaaa = 9; //cc  allways do work well here

   Soo localeSoo;

   localeSoo.; // <-- cc do nothing


When we meet the first semicolon, we need to clear the typed namespace, because this is always the end of a statement.

Edit:

Is is possible to add a private function named ClearTypedNamespace() :D
Because these codes exist in many places.
Title: Re: CC fail after A class's static method called.
Post by: blueshake on December 15, 2009, 11:10:02 AM
confirm it.Thanks. O(∩_∩)O~
Title: Re: CC fail after A class's static method called.
Post by: MortenMacFly on December 15, 2009, 01:06:54 PM
Quote from: ollydbg on December 15, 2009, 10:45:41 AM
This patch can simply fix the bug.
Confirmed && applied. Thanks! :-)