News:

When registered with our forums, feel free to send a "here I am" post here to differ human beings from SPAM bots.

Main Menu

BUG: Auto-Completion with namespace

Started by darksquall57, January 30, 2014, 09:10:03 AM

Previous topic - Next topic

darksquall57

Hi,

I just found a bug that makes the auto-completion not working when using a namespace.
I'm using this base code :


namespace nBase {

class A
{
public:
    int ObjectA() const { return mObjectA; }
public:
    int mObjectA;
};

class B :
    public A
{
public:
    int mObjectB;
};

}

int main()
{
    return 0;
}


Here is what happens:

int main()
{
//----
    ::nBase:: //Autocompletion ok
//----
    ::nBase::B b;
    b. //Autocompletion ok
//----
    ::nBase::B:: //Here AutoCompletion doesn't popup
    return 0;
}


If I remove the namespace nBase, then everything works fine.

I'm running Codeblocks rev9594 64bits on Ubuntu 12.04, but I've noticed this bug a long time ago. It's only now that I've found what's really happening.

ollydbg

Hi, darksquall57, thanks for the report.
I can confirm this bug, I did a git blame, and found this bug was introduced in svn rev
Revision: 0da216bc5e6471b760be10b3e47b9445a981d37d
Author: mortenmacfly <mortenmacfly@2a5c6006-c6dd-42ca-98ab-0921f2732cef>
Date: 2010-8-16 12:42:07
Message:
* cc_branch: applied patch to fix global scope search failed

git-svn-id: http://svn.code.sf.net/p/codeblocks/code/branches/codecompletion_refactoring@6485 2a5c6006-c6dd-42ca-98ab-0921f2732cef
----
Modified: src/plugins/codecompletion/codecompletion.cpp
Modified: src/plugins/codecompletion/nativeparser.cpp


This line was added:

    else if (lineFirstChar == _T(':') && curChar == _T(':'))
        return;

in the function: void CodeCompletion::DoCodeComplete().

In you case:
::nBase::B::
It matches this condition, so this function just returned......



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.

MortenMacFly

Quote from: ollydbg on January 30, 2014, 04:58:14 PM
I can confirm this bug, I did a git blame, and found this bug was introduced in svn rev
Well but you also see why: Because otherwise global scope will not work. So be careful and do not just revert this change.
Compiler logging: Settings->Compiler & Debugger->tab "Other"->Compiler logging="Full command line"
C::B Manual: [url="https://www.codeblocks.org/docs/main_codeblocks_en.html"]https://www.codeblocks.org/docs/main_codeblocks_en.html[/url]
C::B FAQ: [url="https://wiki.codeblocks.org/index.php?title=FAQ"]https://wiki.codeblocks.org/index.php?title=FAQ[/url]

darksquall57


ollydbg

Quote from: MortenMacFly on January 30, 2014, 05:30:44 PM
Quote from: ollydbg on January 30, 2014, 04:58:14 PM
I can confirm this bug, I did a git blame, and found this bug was introduced in svn rev
Well but you also see why: Because otherwise global scope will not work. So be careful and do not just revert this change.
This is the change of that commit:
0da216bc5e6471b760be10b3e47b9445a981d37d
src/plugins/codecompletion/codecompletion.cpp | 9 +++++++--
src/plugins/codecompletion/nativeparser.cpp   | 4 ++--
2 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/src/plugins/codecompletion/codecompletion.cpp b/src/plugins/codecompletion/codecompletion.cpp
index 2f41040..9709d6e 100644
--- a/src/plugins/codecompletion/codecompletion.cpp
+++ b/src/plugins/codecompletion/codecompletion.cpp
@@ -1397,7 +1397,10 @@ void CodeCompletion::DoCodeComplete()
    const int style = control->GetStyleAt(pos);
    const int lineIndentPos = control->GetLineIndentPosition(control->GetCurrentLine());

-    if (ed->GetControl()->GetCharAt(lineIndentPos) == _T('#'))
+    const wxChar lineFirstChar = ed->GetControl()->GetCharAt(lineIndentPos);
+    const wxChar curChar = ed->GetControl()->GetCharAt(pos - 1);
+
+    if (lineFirstChar == _T('#'))
    {
        const int start = control->WordStartPosition(lineIndentPos + 1, true);
        const int end = control->WordEndPosition(lineIndentPos + 1, true);
@@ -1409,7 +1412,9 @@ void CodeCompletion::DoCodeComplete()
            CodeCompletePreprocessor();
        return;
    }
-    else if (ed->GetControl()->GetCharAt(pos - 1) == _T('#'))
+    else if (curChar == _T('#'))
+        return;
+    else if (lineFirstChar == _T(':') && curChar == _T(':'))
        return;

    if (style != wxSCI_C_DEFAULT && style != wxSCI_C_OPERATOR && style != wxSCI_C_IDENTIFIER)
diff --git a/src/plugins/codecompletion/nativeparser.cpp b/src/plugins/codecompletion/nativeparser.cpp
index cc865b7..3a4c8b7 100644
--- a/src/plugins/codecompletion/nativeparser.cpp
+++ b/src/plugins/codecompletion/nativeparser.cpp
@@ -1917,8 +1917,8 @@ static bool IsOperatorEnd(int startAt, const wxString& line)
}
static bool IsOperatorBegin(int startAt, const wxString& line)
{
-    return (   (startAt > 0)
-            && ((size_t)startAt + 1< line.Len())
+    return (   (startAt >= 0)
+            && ((size_t)startAt < line.Len())
            && (   (   (line.GetChar(startAt ) == '-')
                    && (line.GetChar(startAt + 1) == '>') )
                || (   (line.GetChar(startAt) == ':')


I take some time to read the code and debug some examples, I don't see what exact bug this commit going to fix.

Here is the code I use:

void f1();
void f2();


namespace nBase {

   class A
   {
   public:
       int ObjectA() const { return mObjectA; }
   public:
       int mObjectA;
   };

   class B : public A
   {
   public:
       int mObjectB;
   };

}

int main()
{

   ::f                           // works fine here
   return 0;
}


I don't even understand what does "applied patch to fix global scope search failed" means.

What is the relation ship between the first char and the current char?

+    else if (lineFirstChar == _T(':') && curChar == _T(':'))
        return;

???

Maybe, that patch was created by Loaden? but I think Loaden is not active for a very long time.
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.

ollydbg

Another change I think is wrong:

-- a/src/plugins/codecompletion/nativeparser.cpp
+++ b/src/plugins/codecompletion/nativeparser.cpp
@@ -1917,8 +1917,8 @@ static bool IsOperatorEnd(int startAt, const wxString& line)
}
static bool IsOperatorBegin(int startAt, const wxString& line)
{
-    return (   (startAt > 0)
-            && ((size_t)startAt + 1< line.Len())
+    return (   (startAt >= 0)
+            && ((size_t)startAt < line.Len())
             && (   (   (line.GetChar(startAt ) == '-')
                     && (line.GetChar(startAt + 1) == '>') )
                 || (   (line.GetChar(startAt) == ':')

startAt could be 0, that's Ok, but we later use line.GetChar(startAt + 1), so it should be the condition (size_t)startAt + 1< line.Len().
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.

ollydbg

int main()
{

    ::                          // cc here
    return 0;
}



If cc after the double colon, then the code goes here:

    else if (lineFirstChar == _T(':') && curChar == _T(':'))
        return;


So, I guess this "else if" condition is going to skip this condition?
If true, I think the logic is not correct, the correct way should be:

    else if (lineFirstChar == _T(':') && curChar == _T(':') && "there is no extra char between linFirstChar and curChar")
        return;


What's your opinion?
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.