Developer forums (C::B DEVELOPMENT STRICTLY!) > CodeCompletion redesign

Is this something we can solve with the improved CC

<< < (4/4)

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