wxStaticText* static = new wxStaticText(this, wxID_ANY, label, pos, size, style, name);
#include <iostream>
using namespace std;
class AAA
{
public:
AAA(){};
int a;
};
int main()
{
AAA * p = new AAA();
cout << "Hello world!" << endl;
return 0;
}
loaden 2010-11-2 22:30:23
* special handle constructor function for 'Goto declaration' and 'Goto implementation'
if (isClassOrConstructor)
{
const bool isConstructor = (GetNextNonWhitespaceChar(editor->GetControl(), end) == _T('('));
for (TokenIdxSet::iterator it = result.begin(); it != result.end();)
{
Token* tk = tokens->at(*it);
if (isConstructor && tk && tk->m_TokenKind == tkClass)
result.erase(it++); //line 2672 ---------------------------------------------------------------
else if (!isConstructor && tk && tk->m_TokenKind == tkConstructor)
result.erase(it++);
else
++it;
}
}
}
Find Declaration of constructor still doesn't work. 2014 year now.Indeed, it is not fixed. Now, I need some suggestions.
Instead of showing declaration of constructor it shows declaration of class.
Code::blocks svn 9455.
#include <iostream>
using namespace std;
class AAA //-----------------------(a)
{
public:
AAA(){}; //-----------------------(b)
int a;
};
int main()
{
AAA * p = new AAA();
^^^----------------------------------------------(1)
^^^-------------------------------(2)
cout << "Hello world!" << endl;
return 0;
}
#include <iostream>
using namespace std;
class AAA
{
public:
AAA(int b){};
int a;
};
class BBB
{
public:
int a;
};
int main()
{
AAA * p = new AAA(6);
BBB * p = new BBB(6);
cout << "Hello world!" << endl;
return 0;
}
case 1: find declaration in (1) should go to (a), not (b)
case 2: find declaration in (2) should go to (b), not (a)
From a204e285017afe0aa41e4660b0eaa2a59504aaed Mon Sep 17 00:00:00 2001
From: asmwarrior
Date: Sun, 26 Jan 2014 14:19:04 +0800
Subject: [PATCH] * CC: find declaration of a class constructor goes to the
correct constructor functions, not the class definition. This fix a bug
reported here:
http://forums.codeblocks.org/index.php/topic,13753.msg92654.html#msg92654
---
src/plugins/codecompletion/codecompletion.cpp | 41 ++++++++++--------------
src/plugins/codecompletion/nativeparser_base.cpp | 36 ++++++++++++++++++++-
src/plugins/codecompletion/nativeparser_base.h | 3 ++
3 files changed, 55 insertions(+), 25 deletions(-)
diff --git a/src/plugins/codecompletion/codecompletion.cpp b/src/plugins/codecompletion/codecompletion.cpp
index ba48475..1fc3af5 100644
--- a/src/plugins/codecompletion/codecompletion.cpp
+++ b/src/plugins/codecompletion/codecompletion.cpp
@@ -2219,34 +2219,27 @@ void CodeCompletion::OnGotoDeclaration(wxCommandEvent& event)
}
}
}
- // special handle constructor function
- else
+ else // special handle constructor and functions
{
- bool isClassOrConstructor = false;
- for (TokenIdxSet::const_iterator it = result.begin(); it != result.end(); ++it)
+ // AAA * p = new AAA();
+ // ^^^---------------------------------------------this should go to class definition
+ // ^^^-------------------------------this should go to functions such as constructors
+ const bool isFunction = CodeCompletionHelper::GetNextNonWhitespaceChar(editor->GetControl(), endPos) == _T('(');
+ TokenIdxSet savedResult = result;
+ for (TokenIdxSet::const_iterator it = result.begin(); it != result.end();)
{
const Token* token = tree->at(*it);
- if (token && (token->m_TokenKind == tkClass || token->m_TokenKind == tkConstructor))
- {
- isClassOrConstructor = true;
- break;
- }
- }
- if (isClassOrConstructor)
- {
- const bool isConstructor = CodeCompletionHelper::GetNextNonWhitespaceChar(editor->GetControl(), endPos) == _T('(')
- && CodeCompletionHelper::GetLastNonWhitespaceChar(editor->GetControl(), startPos) == _T(':');
- for (TokenIdxSet::const_iterator it = result.begin(); it != result.end();)
- {
- const Token* token = tree->at(*it);
- if (isConstructor && token && token->m_TokenKind == tkClass)
- result.erase(it++);
- else if (!isConstructor && token && token->m_TokenKind == tkConstructor)
- result.erase(it++);
- else
- ++it;
- }
+ if (isFunction && token && token->m_TokenKind == tkClass)
+ result.erase(it++); // a class token is removed
+ else if (!isFunction && token && token->m_TokenKind == tkConstructor)
+ result.erase(it++); // a constructor token is removed
+ else
+ ++it;
}
+ // in a special case that a class definition don't have a constructor defined (implicitly defined by compiler)
+ // add shouldn't remove those class type tokens, so we need to restore the saved result
+ if (!result.size())
+ result = savedResult;
}
// special handle for function overloading
diff --git a/src/plugins/codecompletion/nativeparser_base.cpp b/src/plugins/codecompletion/nativeparser_base.cpp
index ee06770..3b8a02f 100644
--- a/src/plugins/codecompletion/nativeparser_base.cpp
+++ b/src/plugins/codecompletion/nativeparser_base.cpp
@@ -964,11 +964,45 @@ size_t NativeParserBase::ResolveExpression(TokenTree* tree,
}// while
if (!initialScope.empty())
- result = initialScope;
+ {
+ // if a Token in initialScope is a class, and we need to add its public constructors, this
+ // is useful when we try to find declaration of a constructor, see
+ // http://forums.codeblocks.org/index.php/topic,13753.msg92654.html#msg92654
+ AddConstructors(tree, initialScope, result);
+ }
return result.size();
}
+void NativeParserBase::AddConstructors(TokenTree *tree, const TokenIdxSet& source, TokenIdxSet& dest)
+{
+ for (TokenIdxSet::iterator It = source.begin(); It != source.end(); ++It)
+ {
+ const Token* token = tree->at(*It);
+ if (!token)
+ continue;
+ dest.insert(*It);
+
+ // add constructors of the class type token
+ if (token->m_TokenKind == tkClass)
+ {
+ // loop on its children, add its public constructors
+ for (TokenIdxSet::iterator chIt = token->m_Children.begin();
+ chIt != token->m_Children.end();
+ ++chIt)
+ {
+ const Token* tk = tree->at(*chIt);
+ if ( tk && ( tk->m_TokenKind == tkConstructor
+ || (tk->m_IsOperator && tk->m_Name.EndsWith(wxT("()"))) )
+ && (tk->m_Scope == tsPublic || tk->m_Scope == tsUndefined) )
+ {
+ dest.insert(*chIt);
+ }
+ }
+ }
+ }
+}
+
void NativeParserBase::ResolveOperator(TokenTree* tree,
const OperatorType& tokenOperatorType,
const TokenIdxSet& tokens,
diff --git a/src/plugins/codecompletion/nativeparser_base.h b/src/plugins/codecompletion/nativeparser_base.h
index fc25c04..b2cff33 100644
--- a/src/plugins/codecompletion/nativeparser_base.h
+++ b/src/plugins/codecompletion/nativeparser_base.h
@@ -449,6 +449,9 @@ private:
return false;
}
+ /** loop on the source Token set, and add all its public constructors to dest */
+ void AddConstructors(TokenTree *tree, const TokenIdxSet& source, TokenIdxSet& dest);
+
// for GenerateResultSet()
bool MatchText(const wxString& text, const wxString& target, bool caseSens, bool isPrefix)
{
--
1.8.5.2.msysgit.0
Comments?You know mine: Cannot try as the patch does not apply. :)
There is a translation that should apply with svn: http://cmpt.benbmp.org/codeblocks/patches/cc.ollydbg.svn.patchThanks for the conversion.
ollydbg: your git patch is missing the email address and fails to apply cleanly with git am, please fix it.I just manually delete the email address to anti-SPAM, ;). I will use a dummy email address next time.
I see ollydbg's patch is trying to handle both the "go to declaration" and "go to implementation" cases, so it sounds like a more complete solution (my patch only fixes the "go to impl" case).Yes, I have one, I just search our forum for several minutes, and finally found one: Re: Find Declaration of constructor doesn't work (http://forums.codeblocks.org/index.php/topic,13753.msg129197.html#msg129197).Yes, thats the one I recall. Well - if Hukis patch provides the same results I would vote for that instead, because it looks a bit simpler.
cbEditor* cbedpp = new cbEditor(par, file, name, theme);
^^^^^^^^
const bool isConstructor = CodeCompletionHelper::GetNextNonWhitespaceChar(editor->GetControl(), endPos) == _T('(')
&& CodeCompletionHelper::GetLastNonWhitespaceChar(editor->GetControl(), startPos) == _T(':');
const bool isConstructor = CodeCompletionHelper::GetNextNonWhitespaceChar(editor->GetControl(), endPos) == _T('(');
// in a special case that a class definition don't have a constructor defined (implicitly defined by compiler)
// add shouldn't remove those class type tokens, so we need to restore the saved result
if (!result.size())
result = savedResult;
Let's still look at the sample code in this Re: Find Declaration of constructor doesn't work (http://forums.codeblocks.org/index.php/topic,13753.msg92783.html#msg92783)Ok, I think your AddConstructors() code was trying to achieve "case 3". My opinion is that only case 1 and 2 are required (i.e., find decl in (1) should only go to (a), the struct name).
What is the expect behavior?Code#include <iostream>
using namespace std;
class AAA //-----------------------(a)
{
public:
AAA(){}; //-----------------------(b)
int a;
};
int main()
{
AAA * p = new AAA();
^^^----------------------------------------------(1)
^^^-------------------------------(2)
cout << "Hello world!" << endl;
return 0;
}
So, here is my rules:
case 1: find declaration in (1) should go to (a), not (b)
case 2: find declaration in (2) should go to (b), not (a)
But
case 3: do you think that find declaration in (1) should go to show a list box showing both (a) and (b), and let the user select where to go?
I think Alpha has did some work which is quite similar to the solution of this issue, see the SVN commit WebSVN - codeblocks - Rev 9560 - / (http://cb.biplab.in/websvn/revision.php?repname=codeblocks&path=%2F&rev=9560&peg=9560), but that's only for call-tip.In fact I have some improvements for the calltips (typedef and macro functions), I'll test Alpha's patch when I'm going to submit those.
Question again here, does call-tip need to show a class definition Token? I basically think that a call-tip should show only a function prototype tip, unless this class does not have a constructor.
wxStaticText* static = new wxStaticText(|
wxStaticText static(|
class BBB
{
public:
int a;
};
BBB * p = new BBB(6);
class AAA
{
public:
AAA(int b){};
int a;
};
int main()
{
AAA * p = new AAA(6);
Hi, Huki, sorry for the late reply, I'm busy those days.No problem.
I now understand. I was confused about the sentence in bold because in my initial tests, the constructors were actually added to the result even without your AddConstructors() patch (and I got the "Multiple matches" dialog). But that was only because I was already inside the class scope when performing the "go to impl". In other cases (as in your example code) the AddConstructors() is indeed required.CodeWhen user hover on "AAA(6)", we also do a search by keyword "AAA" in our Token (under the global scope and main() function body), then still you get one result "class Token AAA". Note here the constructor AAA is not in the result, because the constructor is a child Token of the class Token AAA. As a general rule, if an identifier is followed by a '(', this gives a hint that user need to go to some function like Tokens. So, I add the function AddConstructors(), which in the last stage of ResolveExpression(). So that both "class Token AAA" and "constructor AAA" is returned.class AAA
{
public:
AAA(int b){};
int a;
};
int main()
{
AAA * p = new AAA(6);
Later, "class Token AAA" is removed from the result, so we go to the correct declaration of the constructor.
I'm not sure my patch is going to handle "go to implementation xxxxx", I just think it solve some "go to declaration xxxx" issue.I tested your patch and can confirm it handles both cases as expected.
...Hi, Huki, thanks for the test and discussion. Now, the patch is in trunk (r9756).
I tested your patch and can confirm it handles both cases as expected.
So I'm ok about committing your entire patch. :)