Author Topic: bug: ~XXX is always recognized as a destructor  (Read 14427 times)

Offline ollydbg

  • Developer
  • Lives here!
  • *****
  • Posts: 6023
  • OpenCV and Robotics
    • Chinese OpenCV forum moderator
bug: ~XXX is always recognized as a destructor
« on: June 11, 2014, 03:47:08 am »
From discussion:
Re: The 24 May 2014 build (9778) is out.


Use the git blame, I found this bug happens in this commit.

Code
Revision: 158fe092f69424861b309078741e38e7bec2c0cc
Author: loaden <loaden@2a5c6006-c6dd-42ca-98ab-0921f2732cef>
Date: 2010-11-2 21:29:18
Message:
* special handle destructor function for 'Goto declaration' and 'Goto implementation'

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



Diff file:
Code
 src/plugins/codecompletion/codecompletion.cpp | 60 ++++++++++++++++++++++-----
 1 file changed, 49 insertions(+), 11 deletions(-)

diff --git a/src/plugins/codecompletion/codecompletion.cpp b/src/plugins/codecompletion/codecompletion.cpp
index ffef317..a5071f6 100644
--- a/src/plugins/codecompletion/codecompletion.cpp
+++ b/src/plugins/codecompletion/codecompletion.cpp
@@ -645,6 +645,27 @@ void CodeCompletion::BuildMenu(wxMenuBar* menuBar)
         Manager::Get()->GetLogManager()->DebugLog(_T("Could not find Project menu!"));
 }
 
+wxChar GetLastNonWhitespaceChar(cbStyledTextCtrl* control, int position)
+{
+    if (!control)
+        return 0;
+
+    while (--position > 0)
+    {
+        const int style = control->GetStyleAt(position);
+        if (control->IsComment(style))
+            continue;
+
+        const wxChar ch = control->GetCharAt(position);
+        if (ch <= _T(' '))
+            continue;
+
+        return ch;
+    }
+
+    return 0;
+}
+
 // invariant : on return true : NameUnderCursor is NOT empty
 bool EditorHasNameUnderCursor(wxString& NameUnderCursor, bool& IsInclude)
 {
@@ -667,21 +688,14 @@ bool EditorHasNameUnderCursor(wxString& NameUnderCursor, bool& IsInclude)
         }
         else
         {
-            int start = control->WordStartPosition(pos, true);
+            const int start = control->WordStartPosition(pos, true);
             const int end = control->WordEndPosition(pos, true);
             const wxString word = control->GetTextRange(start, end);
             if (!word.IsEmpty())
             {
                 NameUnderCursor.Clear();
-                while (--start > 0)
-                {
-                    const wxChar ch = control->GetCharAt(start);
-                    if (ch <= _T(' '))
-                        continue;
-                    else if (ch == _T('~'))
-                        NameUnderCursor << _T("~");
-                    break;
-                }
+                if (GetLastNonWhitespaceChar(control, start) == _T('~'))
+                    NameUnderCursor << _T('~');
                 NameUnderCursor << word;
                 ReturnValue = true;
                 IsInclude = false;
@@ -2573,7 +2587,12 @@ void CodeCompletion::OnGotoDeclaration(wxCommandEvent& event)
     const int pos = editor->GetControl()->GetCurrentPos();
     const int start = editor->GetControl()->WordStartPosition(pos, true);
     const int end = editor->GetControl()->WordEndPosition(pos, true);
-    const wxString target = editor->GetControl()->GetTextRange(start, end);
+    wxString target;
+    if (GetLastNonWhitespaceChar(editor->GetControl(), start) == _T('~'))
+        target << _T('~');
+    target << editor->GetControl()->GetTextRange(start, end);
+    if (target.IsEmpty())
+        return;
 
     // prepare a boolean filter for declaration/implementation
     bool isDecl = event.GetId() == idGotoDeclaration || event.GetId() == idMenuGotoDeclaration;
@@ -2583,6 +2602,25 @@ void CodeCompletion::OnGotoDeclaration(wxCommandEvent& event)
     TokenIdxSet result;
     m_NativeParser.MarkItemsByAI(result, true, false, true, end);
 
+    // special handle destructor function
+    if (target[0] == _T('~'))
+    {
+        TokenIdxSet tmp = result;
+        result.clear();
+
+        TokensTree* tokens = m_NativeParser.GetParser().GetTokens();
+        for (TokenIdxSet::iterator it = tmp.begin(); it != tmp.end(); ++it)
+        {
+            Token* tk = tokens->at(*it);
+            if (tk && tk->m_TokenKind == tkClass)
+            {
+                tk = tokens->at(tokens->TokenExists(target, tk->GetSelf(), tkDestructor));
+                if (tk)
+                    result.insert(tk->GetSelf());
+            }
+        }
+    }
+
     // one match
     Token* token = NULL;
     if (result.size() == 1)


Issue:
Code
+    if (GetLastNonWhitespaceChar(editor->GetControl(), start) == _T('~'))
+        target << _T('~');
Maybe, this is the bug.
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 damorin

  • Multiple posting newcomer
  • *
  • Posts: 52
Re: bug: ~XXX is always recognized as a destructor
« Reply #1 on: June 11, 2014, 07:11:42 pm »
Hi,

sounds exactly like it.

Adding a check for C++ project (or file) should be enough to fix it.

One problem at a time and we will get there.

Offline ollydbg

  • Developer
  • Lives here!
  • *****
  • Posts: 6023
  • OpenCV and Robotics
    • Chinese OpenCV forum moderator
Re: bug: ~XXX is always recognized as a destructor
« Reply #2 on: June 12, 2014, 06:18:50 am »
Hi,

sounds exactly like it.

Adding a check for C++ project (or file) should be enough to fix it.


Hi, ~ can either be logic operator or the destructor prefix, so, why do you think adding a check for C++ project can solve this?
« Last Edit: June 12, 2014, 07:27:32 am by ollydbg »
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 damorin

  • Multiple posting newcomer
  • *
  • Posts: 52
Re: bug: ~XXX is always recognized as a destructor
« Reply #3 on: June 12, 2014, 01:03:31 pm »
Hi,

sounds exactly like it.

Adding a check for C++ project (or file) should be enough to fix it.


Hi, ~ can either be logic operator or the destructor prefix, so, why do you think adding a check for C++ project can solve this?

Oops, that would only fix it in C but the problem would remain in C++. It's not that good then unless there is a check to see if it's a destructor or not.



One problem at a time and we will get there.

Offline Huki

  • Multiple posting newcomer
  • *
  • Posts: 95
Re: bug: ~XXX is always recognized as a destructor
« Reply #4 on: June 13, 2014, 08:58:46 pm »
From discussion:
Re: The 24 May 2014 build (9778) is out.

Use the git blame, I found this bug happens in this commit.

...


Hi,
Have to remind you that I posted a patch for this one several weeks ago. :) See here.

Offline ollydbg

  • Developer
  • Lives here!
  • *****
  • Posts: 6023
  • OpenCV and Robotics
    • Chinese OpenCV forum moderator
Re: bug: ~XXX is always recognized as a destructor
« Reply #5 on: June 15, 2014, 01:11:42 pm »
From discussion:
Re: The 24 May 2014 build (9778) is out.

Use the git blame, I found this bug happens in this commit.

...


Hi,
Have to remind you that I posted a patch for this one several weeks ago. :) See here.

Dear Huki, sorry for the delay, I focus my major spare time on other part of CC, and forget your patch.
Now, the patch is in trunk (rev 9794), thanks for your contribution.
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.