Developer forums (C::B DEVELOPMENT STRICTLY!) > CodeCompletion redesign
Is this something we can solve with the improved CC
Loaden:
--- Quote from: ollydbg on April 14, 2010, 09:34:31 am ---
--- Quote from: daniloz on April 14, 2010, 09:25:35 am ---Cool!!! That's something I was waiting for a while now... :D
The other thing is to parse #ifdef statements and parse only the relevant code, but this one I know is a though one... ;-)
--- End quote ---
Ok, I will help if I have time.
By the way, these days, Loaden has implementing a mechanism to handle #if #ifdef like statement. He has release his code in
http://topic.csdn.net/u/20100412/21/b39c50b9-caeb-406f-a12e-023e088c78c9.html It is a Chinese programming site.
He has not finished it yet, because he has failed parsing the statement like below:
--- Code: ---#if (2 - 1) + !((3 - 2) ^ 1)
--- End code ---
Resolving the expression is not quite easy.
--- End quote ---
I have solved this problem, after repeated tests, and now it works well.
[attachment deleted by admin]
ollydbg:
@Ceniza
firstly, thanks for the hint, the calculation of expression value in your CCPP code is still a bit hard for me, so you can see, in CC_BRANCH, we still use another way. (CC_branch has a way to calculate the #if XXX kind of conditional preprocessor value now).
I have some time to test your CCPP project. I'm using it under MinGW.
To build the lib, we need to do a modification in the file:
include\stdstring.h
Under Windows, the function sprintf is not under std namespace, instead, you need to add the #include <cstdio>
--- Code: --- /**
\brief Creates a new STDString from an \c int value.
\param value Value to convert.
\return New STDString containing the string representation of
\p value.
*/
static STDString fromInt(int value) { char buffer[24]; std::sprintf(buffer, "%d", value); return STDString(buffer); }
--- End code ---
Also, I have find a bug, When I'm running your test-debug target, I set the argument like this:
../../tests/file_line.cpp
So, the file_line.cpp will be parsed.
Here is the log output:
--- Code: ---const char * fGetFILE ( ) {
return "bwehehe.h" ;
}
int fGetLINE ( ) {
return 58 ;
}
# define getLINE ( ) 201 int main ( ) {
int line0 = 206 ;
int line1 = getLINE ( ) ;
const char * file1 = "src/test/../../tests/file_line.cpp" ;
int line2 = fGetLINE ( ) ;
const char * file2 = fGetFILE ( ) ;
const char * today = "Jul 04 2010" ;
const char * now = "20:52:31" ;
int cpp = 199711L ;
}
Process returned 0 (0x0) execution time : 0.047 s
Press any key to continue.
--- End code ---
See the log :
--- Code: ---int line1 = getLINE ( ) ;
--- End code ---
But in the file_line.cpp, the getLine() is defined by a macro.
file_line.cpp
--- Code: ---#line 200
#include "file_line.h"
#define getLINE() __LINE__
int main()
{
#if __LINE__ == 205
int line0 = __LINE__;
#endif
int line1 = getLINE();
const char *file1 = getFILE();
int line2 = fGetLINE();
const char *file2 = fGetFILE();
const char *today = __DATE__;
const char *now = __TIME__;
int cpp = __cplusplus;
}
--- End code ---
So, it should output the current line number instead of getLINE().
BTW: it seems the CCPP project was currently develop freeze, would like to improve it or you just abandon it?
Thanks.
ollydbg:
@killerbot and all.
See this function:
--- Code: ---void CodeCompletion::OnValueTooltip(CodeBlocksEvent& event)
{
event.Skip();
if (IsAttached() && m_InitDone)
{
if (!Manager::Get()->GetConfigManager(_T("code_completion"))->ReadBool(_T("eval_tooltip"), true))
return;
EditorBase* base = event.GetEditor();
cbEditor* ed = base && base->IsBuiltinEditor() ? static_cast<cbEditor*>(base) : 0;
if (!ed || ed->IsContextMenuOpened())
return;
if (ed->GetControl()->CallTipActive())
ed->GetControl()->CallTipCancel();
// Manager::Get()->GetLogManager()->DebugLog(F(_T("CodeCompletion::OnValueTooltip: %p"), ed));
/* NOTE: The following 2 lines of codes can fix [Bug #11785].
* The solution may not the best one and it requires the editor
* to have the focus (even if C::B has the focus) in order to pop-up the tooltip. */
if (wxWindow::FindFocus() != static_cast<wxWindow*>(ed->GetControl()))
return;
// ignore comments, strings, preprocesor, etc
int style = event.GetInt();
if ( (style != wxSCI_C_DEFAULT)
&& (style != wxSCI_C_OPERATOR)
&& (style != wxSCI_C_IDENTIFIER) )
return;
int pos = ed->GetControl()->PositionFromPointClose(event.GetX(), event.GetY());
if (pos < 0 || pos >= ed->GetControl()->GetLength())
return;
Parser* parser = m_NativeParser.GetParserPtr();
if (parser)
{
TokenIdxSet result;
int endOfWord = ed->GetControl()->WordEndPosition(pos, true);
if (m_NativeParser.MarkItemsByAI(result, true, true, true, endOfWord))
{
wxString msg;
int count = 0;
for (TokenIdxSet::iterator it = result.begin(); it != result.end(); ++it)
{
Token* token = parser->GetTokens()->at(*it);
if (token)
{
msg << token->DisplayName() << _T("\n");
++count;
if (count > 32) // allow max 32 matches (else something is definitely wrong)
{
msg.Clear();
break;
}
}
}
if (!msg.IsEmpty())
{
msg.RemoveLast(); // last \n
ed->GetControl()->CallTipShow(pos, msg);
// Manager::Get()->GetLogManager()->DebugLog(F(msg));
}
}
}
}
}
--- End code ---
and the function call:
--- Code: ---m_NativeParser.MarkItemsByAI(result, true, true, true, endOfWord)
--- End code ---
after this function call, the result will contains the "Token" you suggests. :D, because MarkItemsByAI do consider the "scopes" of the current word.
killerbot:
so it looks we are ably to solve the problem, are you taking this change into account in your CC refactorings ?
ollydbg:
--- Quote from: killerbot on July 25, 2010, 04:42:38 pm ---so it looks we are ably to solve the problem, are you taking this change into account in your CC refactorings ?
--- End quote ---
partially Yes.
Your problem about "virtual function" still has some bug. But I have create another sample code, and can show how it works:
--- Code: ---int Method1(int arg);
class Other
{
public:
int Method1(int Arg);
};
class ITest
{
public:
virtual int Method1(int Arg) = 0;
};
class Test : public ITest
{
public:
int Method1(int Arg);
};
int Test::Method1(int Arg)
{
return Arg;
}
int main()
{
Test Hello;
std::cout << Hello.Method1(5);
return 0;
}
--- End code ---
In this example, I add Two "function" named "Method1". Now, if I right click on the "Hello.Method1(5)", and select "goto declaration", you will still show the:
--- Code: ---* the ITest declaration
* the Test declaration
--- End code ---
But pay attention:
We don't have the "global function Method1" and the "Other::Method1" included.
Here is the modified code:
--- Code: ---void CodeCompletion::OnGotoDeclaration(wxCommandEvent& event)
{
EditorManager* edMan = Manager::Get()->GetEditorManager();
// killerbot : the menu and right click pop up menu ensured there is a name under the cursor
// BUT it seems the shortcut keys are not disabled although there menu counter part is
// ---> so check is needed and gracefully shut up when the Name under the cursor is empty
bool MoveOn = false;
wxString NameUnderCursor;
bool IsInclude = false;
if (EditorHasNameUnderCursor(NameUnderCursor, IsInclude))
{
if (!IsInclude)
{ // alright move on
MoveOn = true;
}
}
if (!MoveOn)
return;
Parser* parser = m_NativeParser.GetParserPtr();
if (!parser)
return;
// prepare a boolean filter for declaration/implementation
bool isDecl = event.GetId() == idGotoDeclaration || event.GetId() == idMenuGotoDeclaration;
bool isImpl = event.GetId() == idGotoImplementation || event.GetId() == idMenuGotoImplementation;
// get the matching set
Token* token = 0;
TokenIdxSet result;
//parser->GetTokens()->FindMatches(NameUnderCursor, result, true, false);
//Added by Asmwarrior
// ignore comments, strings, preprocesor, etc
int style = event.GetInt();
if ( (style != wxSCI_C_DEFAULT)
&& (style != wxSCI_C_OPERATOR)
&& (style != wxSCI_C_IDENTIFIER) )
return;
cbEditor* ed = Manager::Get()->GetEditorManager()->GetBuiltinActiveEditor();
if (!ed)
return;
const int pos = ed->GetControl()->GetCurrentPos();
int endOfWord = ed->GetControl()->WordEndPosition(pos, true);
m_NativeParser.MarkItemsByAI(result, true, true, true, endOfWord);
//cbMessageBox(wxString::Format(_("TEST: %s %d"), NameUnderCursor.c_str(), result.size()), _("Warning"), wxICON_WARNING);
// one match
if (result.size() == 1)
{
Token* sel = parser->GetTokens()->at(*(result.begin()));
if ((isImpl && !sel->GetImplFilename().IsEmpty()) ||
(isDecl && !sel->GetFilename().IsEmpty()))
{
token = sel;
}
}
// if more than one match, display a selection dialog
else if (result.size() > 1)
{
// TODO: we could parse the line containing the text so
// if namespaces were included, we could limit the results (and be more accurate)
wxArrayString selections;
wxArrayInt int_selections;
for (TokenIdxSet::iterator it = result.begin(); it != result.end(); ++it)
{
Token* sel = parser->GetTokens()->at(*it);
if (sel)
{
// only match tokens that have filename info
if ( (isImpl && !sel->GetImplFilename().IsEmpty())
|| (isDecl && !sel->GetFilename().IsEmpty()) )
{
selections.Add(sel->DisplayName());
int_selections.Add(*it);
}
}
}
if (selections.GetCount() > 1)
{
int sel = wxGetSingleChoiceIndex(_("Please make a selection:"), _("Multiple matches"), selections);
if (sel == wxNOT_FOUND)
return;
token = parser->GetTokens()->at(int_selections[sel]);
}
else if (selections.GetCount() == 1)
{ // number of selections can be < result.size() due to the if tests, so in case we fall
// back on 1 entry no need to show a selection
token = parser->GetTokens()->at(int_selections[0]);
}
}
// do we have a token?
if (token)
{
if (isImpl)
{
if (cbEditor* ed = edMan->Open(token->GetImplFilename()))
{
ed->GotoLine(token->m_ImplLine - 1);
}
else
{
cbMessageBox(wxString::Format(_("Implementation not found: %s"), NameUnderCursor.c_str()), _("Warning"), wxICON_WARNING);
}
}
else
{
if (cbEditor* ed = edMan->Open(token->GetFilename()))
{
ed->GotoLine(token->m_Line - 1);
}
else
{
cbMessageBox(wxString::Format(_("Declaration not found: %s"), NameUnderCursor.c_str()), _("Warning"), wxICON_WARNING);
}
}
}
else
{
cbMessageBox(wxString::Format(_("Not found: %s"), NameUnderCursor.c_str()), _("Warning"), wxICON_WARNING);
}
}
--- End code ---
To your problem:
We should loop of the result TokenIdxSet, then strip out the redundant virtual function declarations, but sometimes as Morten said, this is not a good idea. :D
Navigation
[0] Message Index
[*] Previous page
Go to full version