vipnt::CStop::Configure
vipnt::CStop::m_Angle
#ifndef _STOP_H_INCLUDE
#define _STOP_H_INCLUDE
namespace vipnt
{
class CStop
{
public:
void RePaint();
bool HasWork() const;
private:
int* m_Angle;
int* m_Variance;
};
} // namespace vipnt
#endif // _STOP_H_INCLUDE
#include "Stop.h"
namespace vipnt
{
namespace
{
const int NumberOfZones = 6;
} // namespace
bool CStop::HasWork() const
{
return true;
} // end of HasWork
void CStop::RePaint()
{
} // end of RePaint
} // namespace vipnt
namespace vipnt
{
namespace
{
const int NumberOfZones = 6;
}
...
why not add some kind of functionality/application test for the code completion.Absolutely true!
namespace vipntif we give the anonymous namespace a name .for example qq.
{
namespace
{
const in NumberOfZones = 6;
}
...
#if wxCHECK_VERSION(2, 9, 0)
Manager::Get()->GetLogManager()->DebugLog(F(_T("Current function: %s (at line %d)"), token->DisplayName().wx_str(), token->m_ImplLine));
#else
Manager::Get()->GetLogManager()->DebugLog(F(_T("Current function: %s (at line %d)"), token->DisplayName().c_str(), token->m_ImplLine));
#endif
namespaceAre you aware that this is NOT a legal paragraph? There is no type called "in"... I guess it should read "int". The parser gets confused by that probably. If I change the type to "int" it works pretty well here (latest CC from trunk).
{
const in NumberOfZones = 6;
}
@Morton : how come so many cc stuff works for you and not for us ?? ;-)Dunno. It's really the same code as in trunk now. However - if it makes you "feel better" (;-)): I know at least one class that works for Jens and blueshake but not for me. :-(
This one does not work for me either in r5790....which one?
Lieven's sample-code.This one does not work for me either in r5790....which one?
I can confirm that it work at rev 5731 see the snap4 .I noticed the same (I told you and Jens...), but this info (the revision) is not really helpful as it is before the merge.
Index: src/plugins/codecompletion/parser/parserthread.cpp
===================================================================
--- src/plugins/codecompletion/parser/parserthread.cpp (revision 5816)
+++ src/plugins/codecompletion/parser/parserthread.cpp (working copy)
@@ -1051,7 +1051,11 @@
if (ns == ParserConsts::opbrace)
{
// parse inside anonymous namespace
+ Token* lastParent = m_pLastParent;
+ TokenScope lastScope = m_LastScope;
DoParse();
+ m_pLastParent = lastParent;
+ m_LastScope = lastScope;
}
else
{
hello,did anyboby notice that codecompletion bar that miss some function in codecompletion.cpp.Hi, I can confirm this bug in my local copy(based on rev 5816). :D
see my snap3 .I can confirm that it work at rev 5731 see the snap4 .
it seems that the codecompletion's member function were not included in this situation.what is going on ?
wxArrayString GetIncludeDirs(cbProject &project)
{
wxArrayString dirs;
{
wxArrayString target_dirs = project.GetIncludeDirs();
for(size_t ii = 0; ii < target_dirs.GetCount(); ++ii)
{
wxFileName filename;
NormalizePath(filename, target_dirs[ii]);
wxString fullname = filename.GetFullPath();
fullname.Replace(_T("\\"), _T("/"), true);
if(dirs.Index(fullname) == wxNOT_FOUND)
dirs.Add(fullname);
}
}
wxString target_name = project.GetActiveBuildTarget();
ProjectBuildTarget *target = project.GetBuildTarget(target_name);
if(target)
{
wxArrayString target_dirs = target->GetIncludeDirs();
for(size_t ii = 0; ii < target_dirs.GetCount(); ++ii)
{
wxFileName filename;
NormalizePath(filename, target_dirs[ii]);
wxString fullname = filename.GetFullPath();
fullname.Replace(_T("\\"), _T("/"), true);
if(dirs.Index(fullname) == wxNOT_FOUND)
dirs.Add(fullname);
}
}
return dirs;
}
hello,Morten
goog news: :D
the issue killerbot report can be solved by this patch.
bad news:
can not make a clear explaination here.CodeIndex: src/plugins/codecompletion/parser/parserthread.cpp
===================================================================
--- src/plugins/codecompletion/parser/parserthread.cpp (revision 5816)
+++ src/plugins/codecompletion/parser/parserthread.cpp (working copy)
@@ -1051,7 +1051,11 @@
if (ns == ParserConsts::opbrace)
{
// parse inside anonymous namespace
+ Token* lastParent = m_pLastParent;
+ TokenScope lastScope = m_LastScope;
DoParse();
+ m_pLastParent = lastParent;
+ m_LastScope = lastScope;
}
else
{
@ollydbg
can you provide the patch?
I believe there is some connection among reply #19,20,21.if this issue can be solved,
others wil too.
YES, I can confirm this works now !!!I've committed including another very bad parser bug I fixed. It slipped in with the last modification I did before doing the merge... bad boy... SO could your all please try again? Also: I am generally interested in code snippets to test the CC plugin. I am planning to put all of them in a "test" project.
hello,did anyboby notice that codecompletion bar that miss some function in codecompletion.cpp.hello,Morten
see my snap3 .I can confirm that it work at rev 5731 see the snap4 .
it seems that the codecompletion's member function were not included in this situation.what is going on ?
No, the bug you reported in reply #19 is still exist in rev 5817Quotehello,did anyboby notice that codecompletion bar that miss some function in codecompletion.cpp.hello,Morten
see my snap3 .I can confirm that it work at rev 5731 see the snap4 .
it seems that the codecompletion's member function were not included in this situation.what is going on ?
is this issue solved?
I can confirm my reported issues are still fixed with the latest code in svn.
The bug followed the routine .If the golbal function followed some kind of class member function,then the class member function will be not parsed.(e.g. cbeditor.cpp)
int CodeCompletion::CodeComplete()
{
......
}
bool TestIncludeLine(wxString const &line)
{
......
}
wxArrayString GetIncludeDirs(cbProject &project)
{
......
}
......
DoParse() : Loop:m_Str='int ', token='SortCCList'
HandleFunction() : Adding function 'SortCCList': m_Str='int '
HandleFunction() : name='SortCCList', args='(const wxString& first, const wxString& second)', peek='{'
HandleFunction() : Skipped function SortCCList impl. from 440 to 470
HandleFunction() : Add token name='SortCCList', args='(const wxString& first, const wxString& second)', return type='int '
DoParse() : Loop:m_Str='', token='int'
DoParse() : Loop:m_Str='int ', token='CodeCompletion'
DoParse() : Loop:m_Str='int ', token='CodeComplete'
HandleFunction() : Adding function 'CodeComplete': m_Str='int '
HandleFunction() : name='CodeComplete', args='()', peek='{'
HandleFunction() : Skipped function CodeComplete impl. from 473 to 645
HandleFunction() : Add token name='CodeComplete', args='()', return type='int '
DoParse() : Loop:m_Str='', token='bool'
DoParse() : Loop:m_Str='bool ', token='TestIncludeLine'
HandleFunction() : Adding function 'TestIncludeLine': m_Str='bool '
HandleFunction() : name='TestIncludeLine', args='(wxString const &line)', peek='{'
HandleFunction() : Skipped function TestIncludeLine impl. from 648 to 664
HandleFunction() : Add token name='TestIncludeLine', args='(wxString const &line)', return type='bool '
DoParse() : Loop:m_Str='', token='wxArrayString'
DoParse() : Loop:m_Str='wxArrayString ', token='GetIncludeDirs'
HandleFunction() : Adding function 'GetIncludeDirs': m_Str='wxArrayString '
HandleFunction() : name='GetIncludeDirs', args='(cbProject &project)', peek='{'
HandleFunction() : Skipped function GetIncludeDirs impl. from 667 to 2060
HandleFunction() : Add token name='GetIncludeDirs', args='(cbProject &project)', return type='wxArrayString '
************it seems the parser stops here!!!!!!!********************
Reparsing saved files...
Starting batch parsing
....
fullname.Replace(_T("\\"), _T("/"), true);
...
But what about cbeditor.cpp.
It seems there is no statement fullname.Replace(_T("\\"), _T("/"), true); in the file.
HandleFunction() : Adding function 'IsPreprocessor': m_Str='bool '
HandleFunction() : name='IsPreprocessor', args='(int style)', peek='{'
HandleFunction() : Skipped function IsPreprocessor impl. from 269 to 274
HandleFunction() : Add token name='IsPreprocessor', args='(int style)', return type='bool '
DoParse() : Loop:m_Str='', token='bool'
DoParse() : Loop:m_Str='bool ', token='IsCharacterOrString'
HandleFunction() : Adding function 'IsCharacterOrString': m_Str='bool '
HandleFunction() : name='IsCharacterOrString', args='(int style)', peek='{'
HandleFunction() : Skipped function IsCharacterOrString impl. from 277 to 289
HandleFunction() : Add token name='IsCharacterOrString', args='(int style)', return type='bool '
DoParse() : Loop:m_Str='', token='bool'
DoParse() : Loop:m_Str='bool ', token='IsCharacter'
HandleFunction() : Adding function 'IsCharacter': m_Str='bool '
HandleFunction() : name='IsCharacter', args='(int style)', peek='{'
HandleFunction() : Skipped function IsCharacter impl. from 292 to 304
HandleFunction() : Add token name='IsCharacter', args='(int style)', return type='bool '
DoParse() : Loop:m_Str='', token='void'
DoParse() : Loop:m_Str='void ', token='DoBraceCompletion'
HandleFunction() : Adding function 'DoBraceCompletion': m_Str='void '
HandleFunction() : name='DoBraceCompletion', args='(const wxChar& ch)', peek='{'
HandleFunction() : Skipped function DoBraceCompletion impl. from 307 to 3240
HandleFunction() : Add token name='DoBraceCompletion', args='(const wxChar& ch)', return type='void '
Reparsing saved files...
Starting batch parsing
void DoBraceCompletion(const wxChar& ch)
{
cbStyledTextCtrl* control = m_pOwner->GetControl();
int pos = control->GetCurrentPos();
int style = control->GetStyleAt(pos);
if ( IsComment(style) || IsPreprocessor(style) )
return;
if ( ch == _T('\'') )
{
if ( (control->GetCharAt(pos) == ch) && (pos > 1) && (control->GetCharAt(pos-2) != _T('\\')) )
{
control->DeleteBack();
control->GotoPos(pos);
}
else
{
if ( (control->GetCharAt(pos-2) == _T('\\')) || IsCharacterOrString(style) )
return;
control->AddText(ch);
control->GotoPos(pos);
}
return;
}
if ( ch == _T('"') )
{
if ( (control->GetCharAt(pos) == ch) && (pos > 1) && (control->GetCharAt(pos-2) != _T('\\')) )
{
control->DeleteBack();
control->GotoPos(pos);
}
else
{
if ( (control->GetCharAt(pos-2) == _T('\\')) || IsCharacter(style) )
return;
control->AddText(ch);
control->GotoPos(pos);
}
return;
}
if ( IsCharacterOrString(style) )
return;
const wxString leftBrace(_T("([{"));
const wxString rightBrace(_T(")]}"));
int index = leftBrace.find(ch);
const wxString unWant(_T(");\n\r\t\b "));
#if wxCHECK_VERSION(2, 9, 0)
if ((index != wxNOT_FOUND) && (unWant.find(wxUniChar(control->GetCharAt(pos))) != wxNOT_FOUND))
#else
if ((index != wxNOT_FOUND) && (unWant.find(control->GetCharAt(pos)) != wxNOT_FOUND))
#endif
{
control->AddText(rightBrace.GetChar(index));
control->GotoPos(pos);
if (ch == _T('{'))
{
const wxRegEx reg(_T("^[ \t]*{}[ \t]*"));
if (reg.Matches(control->GetCurLine()))
{
control->NewLine();
control->GotoPos(pos);
control->NewLine();
return;
}
}
}
else
{
index = rightBrace.find(ch);
if (index != wxNOT_FOUND)
{
if (control->GetCharAt(pos) == ch)
{
control->DeleteBack();
control->GotoPos(pos);
return;
}
}
}
}
@ollydbg
I comment wxArrayString GetIncludeDirs(cbProject &project)
and void CodeCompletion::CodeCompleteIncludes() function implementation.Then the cc works in the latest cc.
And I test the codes in codecompletion.cpp without any comment in svn 5731.Everything work perfectly.
bool Tokenizer::SkipToChar(const wxChar& ch)
{
// skip everything until we find ch
while(true)
{
while (CurrentChar() != ch && MoveToNextChar()) // don't check EOF when MoveToNextChar already does
;
if (IsEOF())
return false;
if (PreviousChar() != '\\')
break;
else
{
// check for "\\"
if (((m_TokenIndex - 2) >= 0) && ((m_TokenIndex - 2) >= m_BufferLen) && (m_Buffer.GetChar(m_TokenIndex - 2) == '\\'))
break;
}
MoveToNextChar();
}
return true;
}
// check for "\\"
if (((m_TokenIndex - 2) >= 0) && ((m_TokenIndex - 2) >= m_BufferLen) && (m_Buffer.GetChar(m_TokenIndex - 2) == '\\'))
Index: tokenizer.cpp
===================================================================
--- tokenizer.cpp (revision 5818)
+++ tokenizer.cpp (working copy)
@@ -230,7 +230,7 @@
else
{
// check for "\\"
- if (((m_TokenIndex - 2) >= 0) && ((m_TokenIndex - 2) >= m_BufferLen) && (m_Buffer.GetChar(m_TokenIndex - 2) == '\\'))
+ if (((m_TokenIndex - 2) >= 0) && ((m_TokenIndex - 2) <= m_BufferLen) && (m_Buffer.GetChar(m_TokenIndex - 2) == '\\'))
break;
}
MoveToNextChar();
@@ -286,7 +286,7 @@
else
{
// check for "\\"
- if (((m_TokenIndex - 2) >= 0) && ((m_TokenIndex - 2) >= m_BufferLen) && (m_Buffer.GetChar(m_TokenIndex - 2) == '\\'))
+ if (((m_TokenIndex - 2) >= 0) && ((m_TokenIndex - 2) <= m_BufferLen) && (m_Buffer.GetChar(m_TokenIndex - 2) == '\\'))
break;
}
MoveToNextChar();
I think it should be:Definitely. I'll certainly apply this in trunk when tested. But it really looks very ugly to me, too.
(m_TokenIndex - 2)<= m_BufferLen
Added pointer to here:
http://forums.codeblocks.org/index.php/topic,11240.0.html
(To keep all issues in one place.)
Index: nativeparser.cpp
===================================================================
--- nativeparser.cpp (revision 5819)
+++ nativeparser.cpp (working copy)
@@ -1412,6 +1420,8 @@
static wxString cached_search;
static size_t cached_results_count = 0;
+
+
// early-out opportunity
// if the user starts typing a token that in our last search had 0 results,
// and we see that he's continuing typing for that same token,
@@ -1419,7 +1429,8 @@
if (cached_editor == editor &&
cached_editor_start_word == m_EditorStartWord &&
cached_results_count == 0 &&
- actual.StartsWith(cached_search))
+ actual.StartsWith(cached_search)&&
+ actual.Find(_T('(')) == wxNOT_FOUND)
{
#ifdef DEBUG_CC_AI
if (s_DebugSmartSense)
int aaaa;
void f(int result){
if <---------enter here
}
if
if(
if(resu
static cbEditor* cached_editor = 0;
static int cached_editor_start_word = 0;
static wxString cached_search;
static size_t cached_results_count = 0;
// early-out opportunity
// if the user starts typing a token that in our last search had 0 results,
// and we see that he's continuing typing for that same token,
// don't even bother to search
if (cached_editor == editor &&
cached_editor_start_word == m_EditorStartWord &&
cached_results_count == 0 &&
actual.StartsWith(cached_search)&&
actual.Find(_T('(')) == wxNOT_FOUND) **************************add code here!!!
{
#ifdef DEBUG_CC_AI
if (s_DebugSmartSense)
Manager::Get()->GetLogManager()->DebugLog(_T("Aborting search: last attempt returned 0 results"));
#endif
// but set m_LastAISearchWasGlobal correctly so C++ keywords can be shown
std::queue<ParserComponent> components;
BreakUpComponents(parser, actual, components);
m_LastAISearchWasGlobal = components.size() <= 1;
if (!components.empty())
m_LastAIGlobalSearch = components.front().component;
return 0;
}
Index: src/plugins/codecompletion/nativeparser.cpp
===================================================================
--- src/plugins/codecompletion/nativeparser.cpp (revision 5821)
+++ src/plugins/codecompletion/nativeparser.cpp (working copy)
@@ -1522,6 +1522,7 @@
}
cached_editor = editor;
+ if (result.size() || (m_EditorEndWord - m_EditorStartWord))
cached_editor_start_word = m_EditorStartWord;
cached_search = actual;
cached_results_count = result.size();
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void)
{
struct tm *current;
current->
}
Index: src/plugins/codecompletion/nativeparser.cpp
===================================================================
--- src/plugins/codecompletion/nativeparser.cpp (revision 5824)
+++ src/plugins/codecompletion/nativeparser.cpp (working copy)
@@ -427,71 +427,79 @@
delete [] Compilers;
} // end of AddCompilerDirs
+
+
wxArrayString NativeParser::GetGCCCompilerDirs(const wxString &cpp_compiler, const wxString &base)
{
wxArrayString gcc_compiler_dirs;
// for starters , only do this for gnu compiler
-// Manager::Get()->GetLogManager()->DebugLog(_T("CompilerID ") + CompilerID);
- // wxString Command("mingw32-g++ -v -E -x c++ - < nul");
- // specifying "< nul", does not seem to work
- // workaround : create a dummy file (let's hope it does not exist)
+ //Manager::Get()->GetLogManager()->DebugLog(_T("CompilerID ") + CompilerID);
+ //
+ // windows: mingw32-g++ -v -E -x c++ nul
+ // linux : g++ -v -E -x c++ /dev/null
// do the trick only for c++, not needed then for C (since this is a subset of C++)
- wxString DummyFileName = wxFileName::CreateTempFileName(_T("Dummy_z4hsdkl9nf7ba3L9nv41"));
- if(!DummyFileName.IsEmpty())
+
+
+ // let's construct the command
+ // use a null file handler
+ // both works fine in Windows and linux
+
+#ifdef __WXMSW__
+ wxString Command = cpp_compiler + _T(" -v -E -x c++ nul");
+#else
+ wxString Command = cpp_compiler + _T(" -v -E -x c++ /dev/null");
+#endif
+
+ // action time (everything shows up on the error stream
+ wxArrayString Output, Errors;
+ wxExecute(Command, Output, Errors, wxEXEC_NODISABLE);
+ int nCount = Errors.GetCount();
+ // the include dir (1 per line) show up between the lines
+ // #include <...> search starts here:
+ // End of search list
+ // let's hope this does not change too quickly, otherwise we need
+ // to adjust our search code (for several versions ...)
+ bool bStart = false;
+ for(int idxCount = 0; idxCount < nCount; ++idxCount)
{
- // let's construct the command
- wxString Command = cpp_compiler + _T(" -v -E -x c++ ") + DummyFileName;
- // action time (everything shows up on the error stream
- wxArrayString Output, Errors;
- wxExecute(Command, Output, Errors, wxEXEC_NODISABLE);
- int nCount = Errors.GetCount();
- // the include dir (1 per line) show up between the lines
- // #include <...> search starts here:
- // End of search list
- // let's hope this does not change too quickly, otherwise we need
- // to adjust our search code (for several versions ...)
- bool bStart = false;
- for(int idxCount = 0; idxCount < nCount; ++idxCount)
+ if (!bStart && Errors[idxCount] == _("#include <...> search starts here:"))
{
- if (!bStart && Errors[idxCount] == _("#include <...> search starts here:"))
+ bStart = true;
+ }
+ else if (bStart && Errors[idxCount] == _("End of search list."))
+ {
+ bStart = false; // could jump out of for loop if we want
+ }
+ else if (bStart)
+ {
+// Manager::Get()->GetLogManager()->DebugLog("include dir " + Errors[idxCount]);
+ // get rid of the leading space (more general : any whitespace)in front
+ wxRegEx reg(_T("^[ \t]*(.*)"));
+ if(reg.Matches(Errors[idxCount]))
{
- bStart = true;
- }
- else if (bStart && Errors[idxCount] == _("End of search list."))
- {
- bStart = false; // could jump out of for loop if we want
- }
- else if (bStart)
- {
-// Manager::Get()->GetLogManager()->DebugLog("include dir " + Errors[idxCount]);
- // get rid of the leading space (more general : any whitespace)in front
- wxRegEx reg(_T("^[ \t]*(.*)"));
- if(reg.Matches(Errors[idxCount]))
+ wxString out = reg.GetMatch(Errors[idxCount], 1);
+ if(!out.IsEmpty())
{
- wxString out = reg.GetMatch(Errors[idxCount], 1);
- if(!out.IsEmpty())
+ wxFileName dir(out);
+ if (NormalizePath(dir,base))
{
- wxFileName dir(out);
- if (NormalizePath(dir,base))
- {
- Manager::Get()->GetLogManager()->DebugLog(_T("Caching GCC dir: ") + dir.GetFullPath());
- gcc_compiler_dirs.Add(dir.GetFullPath());
- }
- else
- #if wxCHECK_VERSION(2, 9, 0)
- Manager::Get()->GetLogManager()->DebugLog(F(_T("Error normalizing path: '%s' from '%s'"),out.wx_str(),base.wx_str()));
- #else
- Manager::Get()->GetLogManager()->DebugLog(F(_T("Error normalizing path: '%s' from '%s'"),out.c_str(),base.c_str()));
- #endif
+ Manager::Get()->GetLogManager()->DebugLog(_T("Caching GCC dir: ") + dir.GetFullPath());
+ gcc_compiler_dirs.Add(dir.GetFullPath());
}
+ else
+ #if wxCHECK_VERSION(2, 9, 0)
+ Manager::Get()->GetLogManager()->DebugLog(F(_T("Error normalizing path: '%s' from '%s'"),out.wx_str(),base.wx_str()));
+ #else
+ Manager::Get()->GetLogManager()->DebugLog(F(_T("Error normalizing path: '%s' from '%s'"),out.c_str(),base.c_str()));
+ #endif
}
}
- } // end for : idx : idxCount
- // clean up our temp file
- ::wxRemoveFile(DummyFileName);
- } // Dummy is open
+ }
+ } // end for : idx : idxCount
+
+
return gcc_compiler_dirs;
}
@@ -1209,11 +1217,16 @@
#endif
{
case ']':
- case ')': ++nest; break;
+ case ')': ++nest; --x;break;
case '[':
- case '(': --nest; break;
+ case '(': --nest; --x;break;
+
}
+ while ((x >= 0) && (line.GetChar(x) == ' ' || line.GetChar(x) == '\t'))
+ --x;
+ if ((x >= 0) && (line.GetChar(x) == ')' || line.GetChar(x) == ']'))
+ ++nest;
}
if ((x > 0) && (wxIsalnum(line.GetChar(x - 1)) || line.GetChar(x - 1) == '_'))
--x;
@@ -1268,7 +1281,7 @@
is_function = line.GetChar(startAt) == '(';
++nest;
- while (startAt < line.Length() - 1 && nest != 0)
+ while (startAt < line.Length()-1 && nest != 0)
{
++startAt;
#if wxCHECK_VERSION(2, 9, 0)
@@ -1278,13 +1291,18 @@
#endif
{
case ']':
- case ')': --nest; break;
+ case ')': --nest; ++startAt;break;
case '[':
- case '(': ++nest; break;
+ case '(': ++nest; ++startAt;break;
}
+ while (startAt < line.Length()-1&& (line.GetChar(startAt) == ' ' || line.GetChar(startAt) == '\t'))
+ ++startAt;
+ if (startAt < line.Length()-1 && (line.GetChar(startAt) == '(' || line.GetChar(startAt) == '['))
+ ++nest;
}
- ++startAt;
+ //++startAt;
+
}
//Manager::Get()->GetLogManager()->DebugLog("Return at %d (%c): res=%s", startAt, line.GetChar(startAt), res.c_str());
@@ -1412,6 +1430,8 @@
static wxString cached_search;
static size_t cached_results_count = 0;
+
+
// early-out opportunity
// if the user starts typing a token that in our last search had 0 results,
// and we see that he's continuing typing for that same token,
@@ -1522,6 +1542,7 @@
}
cached_editor = editor;
+ if (result.size() || (m_EditorEndWord - m_EditorStartWord))
cached_editor_start_word = m_EditorStartWord;
cached_search = actual;
cached_results_count = result.size();
Hello, using latest SVN build (and probably not only latest), I am having problem with code completion for variables declared using "struct" keyword. For example:Code#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void)
{
struct tm *current;
current->
}
I dont get any suggestions when typing "current->" and also nothing when trying to complete "curr". It works as expected without keyword struct in declaration.
I tried to find symbol current using Code completion debug tool, but i get only empty list with information, that were found Multiple matches and i must choose :P
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void)
{
struct tm current;
current.
}
I tried to find symbol current using Code completion debug tool, but i get only empty list with information,
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
struct tm * current;
int main(void)
{
current->
}
struct tm * current;
Hello, using latest SVN build (and probably not only latest), I am having problem with code completion for variables declared using "struct" keyword.
struct tm
{
int tm_sec;
int b;
};
struct tm *current;
int main(void)
{
current->
}
I Found a crash, See picture.
At last, I need keyin '\n' but I keyin '\'. it will crash.
I Found a crash, See picture.
At last, I need keyin '\n' but I keyin '\'. it will crash.
I can't reproduce the crash when entering only one statements, can you give a simple testing code?
static wxRegEx rePrint(_T("^(@_@)(.*)"));
void Test_CodeCompletion()
{
static wxString buffer;
wxArrayString lines = GetArrayFromString(buffer, _T('\n'));
bool bMatch=false;
for (unsigned int i = 0; i < lines.GetCount(); ++i)
{
if (rePrint.Matches(lines[i]))
{
lines[i]=_T("");
bMatch=true;
}
}
if(bMatch)
{
buffer.clear();
for (unsigned int i = 0; i < lines.GetCount(); ++i)
{
if(lines[i]!=_T(""))
{
buffer+=lines[i]+_T("\n"); // this line will be crash.
}
}
}
return; // come back later
}
buffer+=lines[i]+_T("\");
I follow you steps, but still can't reproduce this crash.you need create project from wx project template.
By the way, if you enter these statement:Codebuffer+=lines[i]+_T("\");
You will notice that the open brace and the close brace have the different colors. I guess this is caused by Scintilla gramma highlight.
I can more or less confirm this crash on linux.Cool. :D
It does not crash, but it hangs and eats 100 % of one of my CPU's.
Latest svn-source.
I will look into it.
This bug is fixed by this patchdoes it work for codes like these?
#include <iostream>
using namespace std;
struct qq
{
int x;
int y;
};
struct qq tt;
struct qq& xx = tt;
xx.
int main()
{
cout << "Hello world!" << endl;
return 0;
}
I get 100 % of one of my CPU's too, and my codeblocks can not respond to any key.I have this issue too.The programe hang,but 50% of CPU used.
I can more or less confirm this crash on linux.Cool. :D
It does not crash, but it hangs and eats 100 % of one of my CPU's.
Latest svn-source.
I will look into it.
I get 100 % of one of my CPU's too, and my codeblocks can not respond to any key.
QuoteI get 100 % of one of my CPU's too, and my codeblocks can not respond to any key.I have this issue too.The programe hang,but 50% of CPU used.
EDIT:
It seems that (x) tip cause this.
QuoteThis bug is fixed by this patchdoes it work for codes like these?Code#include <iostream>
using namespace std;
struct qq
{
int x;
int y;
};
struct qq tt;
struct qq& xx = tt;
xx.
int main()
{
cout << "Hello world!" << endl;
return 0;
}
struct qq * xx
struct qq & xx
Index: parserthread.cpp
===================================================================
--- parserthread.cpp (revision 5824)
+++ parserthread.cpp (working copy)
@@ -1350,8 +1350,13 @@
HandleFunction(current);
break;
}
- else if (next.GetChar(0) != '*')
+ else if (next.GetChar(0) == '*' || next.GetChar(0) == '&' )
{
+ m_Str<<current;
+ break;
+ }
+ else
+ {
// might be instantiation, see the following
/*
struct HiddenStruct {
@@ -1391,8 +1396,7 @@
}
}
}
- else
- m_Tokenizer.GetToken();
+
}
else
break;
EDIT:
And the issue in this thread seems not solved yet.http://forums.codeblocks.org/index.php/topic,10966.msg74954.html#msg74954 (http://forums.codeblocks.org/index.php/topic,10966.msg74954.html#msg74954)
while ().
wxString NativeParser::GetNextCCToken(const wxString& line, unsigned int& startAt, bool& is_function)
{
wxString res;
int nest = 0;
if ((startAt < line.Length()) && (line.GetChar(startAt) == '('))
{
while (startAt < line.Length() &&
(line.GetChar(startAt) == '*' ||
line.GetChar(startAt) == '&' ||
line.GetChar(startAt) == '('))
{
if (line.GetChar(startAt) == '(')
++nest;
++startAt;
}
}
//Manager::Get()->GetLogManager()->DebugLog(F(_T("at %d (%c): res=%s"), startAt, line.GetChar(startAt), res.c_str()));
while ((startAt < line.Length()) && (wxIsalnum(line.GetChar(startAt)) || line.GetChar(startAt) == '_'))
{
res << line.GetChar(startAt);
++startAt;
}
while ((nest > 0) && (startAt < line.Length()))
{
if (line.GetChar(startAt) == ')')
--nest;
++startAt;
}
//Manager::Get()->GetLogManager()->DebugLog(F(_T("Done nest: at %d (%c): res=%s"), startAt, line.GetChar(startAt), res.c_str()));
while (startAt < line.Length()-1&& (line.GetChar(startAt) == ' ' || line.GetChar(startAt) == '\t'))
++startAt;
if ((startAt < line.Length()) && (line.GetChar(startAt) == '(' || line.GetChar(startAt) == '['))
{
is_function = line.GetChar(startAt) == '(';
++nest;
while (startAt < line.Length()-1 && nest != 0)
{
++startAt;
#if wxCHECK_VERSION(2, 9, 0)
switch (line.GetChar(startAt).GetValue())
#else
switch (line.GetChar(startAt))
#endif
{
case ']':
case ')': --nest; ++startAt;break;
case '[':
case '(': ++nest; ++startAt;break;
}
while (startAt < line.Length()-1&& (line.GetChar(startAt) == ' ' || line.GetChar(startAt) == '\t'))
++startAt;
if (startAt < line.Length()-1 && (line.GetChar(startAt) == '(' || line.GetChar(startAt) == '['))
++nest;
}
//++startAt;
}
//Manager::Get()->GetLogManager()->DebugLog("Return at %d (%c): res=%s", startAt, line.GetChar(startAt), res.c_str());
return res;
}
while (startAt < line.Length()-1&& (line.GetChar(startAt) == ' ' || line.GetChar(startAt) == '\t'))
++startAt;
This is the modified version of the "right search", it just solve this problem in my previous reply.Committed that to trunk (including some other mods). Hence some cases still do not work, check this snippet:
struct _s
{
int x;
float y;
};
typedef struct _s t_s;
int main()
{
struct _s s;
struct _s& rs = s;
struct _s* ps = &s;
t_s ts;
t_s& rts = ts;
t_s* pts = &ts;
s. // works
rs. // works
ps. // works
ps-> // does not work
ts. // works
rts. // works
pts. // works
pts-> // does not work
return 0;
}
This is the modified version of the "right search", it just solve this problem in my previous reply.Committed that to trunk (including some other mods). Hence some cases still do not work, check this snippet:CodeFor ps and pts CC suggests... erm... ps and pts.struct _s
{
int x;
float y;
};
typedef struct _s t_s;
int main()
{
struct _s s;
struct _s& rs = s;
struct _s* ps = &s;
t_s ts;
t_s& rts = ts;
t_s* pts = &ts;
s. // works
rs. // works
ps. // works
ps-> // does not work
ts. // works
rts. // works
pts. // works
pts-> // does not work
return 0;
}
Probably I am missing something... it's late... ;-)
Index: nativeparser.cpp
===================================================================
--- nativeparser.cpp (revision 5826)
+++ nativeparser.cpp (working copy)
@@ -1207,7 +1207,7 @@
--startAt;
return startAt;
}
-static bool IsOperator(int startAt, const wxString& line)
+static bool IsOperatorEnd(int startAt, const wxString& line)
{
return ( (startAt > 0)
&& (startAt < line.Length())
@@ -1216,6 +1216,17 @@
|| ( (line.GetChar(startAt) == ':')
&& (line.GetChar(startAt - 1) == ':') ) ) );
}
+
+static bool IsOperatorBegin(int startAt, const wxString& line)
+{
+ return ( (startAt > 0)
+ && (startAt + 1< line.Length())
+ && ( ( (line.GetChar(startAt ) == '-') )
+ && (line.GetChar(startAt + 1) == '>')
+ || ( (line.GetChar(startAt) == ':')
+ && (line.GetChar(startAt + 1) == ':') ) ) );
+}
+
static bool IsOperatorDot(int startAt, const wxString& line)
{
return ( (startAt >= 0)
@@ -1274,7 +1285,7 @@
}
// Check for [Class]-> ('>' pressed)
// Check for [Class]:: (':' pressed)
- else if (IsOperator(startAt, line))
+ else if (IsOperatorEnd(startAt, line))
{
startAt -= 2;
repeat = true; // yes -> repeat.
@@ -1394,7 +1405,10 @@
++nest;
}
}
+ if (IsOperatorBegin(startAt, line))
+ ++startAt;
+
#if DEBUG_CC_AI
Manager::Get()->GetLogManager()->DebugLog(F(_T("Return at %d (%c): res=%s"), startAt, line.GetChar(startAt), res.c_str()));
#endif
@@ -1446,7 +1460,7 @@
}
// Check for [Class]-> ('>' pressed)
// Check for [Class]:: (':' pressed)
- else if (IsOperator(startAt, line))
+ else if (IsOperatorEnd(startAt, line))
{
if (line.GetChar(startAt) == ':')
tokenType = pttNamespace;
static wxRegEx rePendingBreakpoint(_T("Breakpoint ([0-9]+)[ \\t]\\(\\\"(.+):([0-9]+)\\)[ \\t]pending\\."));
May someboby notice that the cc suggestion list window style is different from the notepad++ whose window
stytle is something like pop menu.So if I want to change the cc suggestion list window style to make it similar with notepad++'s,what should I do?(change what codes, I read the codes,found nothing)
any comment? Thanks!
hi, all.
It seems the parser failed parsing this statement in the gdb_commands.h. (comment this statement can let the parser works ok :D)Codestatic wxRegEx rePendingBreakpoint(_T("Breakpoint ([0-9]+)[ \\t]\\(\\\"(.+):([0-9]+)\\)[ \\t]pending\\."));
char * aaa = "\\\"";
bool Tokenizer::SkipToCharBreak()
{
if (PreviousChar() != '\\')
return true;
else
{
// check for "\\"
if ( ((m_TokenIndex - 2) >= 0)
&& ((m_TokenIndex - 2) <= m_BufferLen)
&& (m_Buffer.GetChar(m_TokenIndex - 2) == '\\') )
return true;
}
return false;
}
char * aaa = "\\\"";
"\\\""
\\
\"
"\\\\\""
or
"\\\\\\\""
Index: tokenizer.cpp
===================================================================
--- tokenizer.cpp (revision 5834)
+++ tokenizer.cpp (working copy)
@@ -216,17 +216,22 @@
bool Tokenizer::SkipToCharBreak()
{
- if (PreviousChar() != '\\')
- return true;
- else
- {
- // check for "\\"
- if ( ((m_TokenIndex - 2) >= 0)
- && ((m_TokenIndex - 2) <= m_BufferLen)
- && (m_Buffer.GetChar(m_TokenIndex - 2) == '\\') )
- return true;
- }
- return false;
+ if (PreviousChar() != '\\')
+ return true;
+ else
+ {
+ // check for "\\"
+ unsigned int numBackslash = 2;
+ while( ((m_TokenIndex - numBackslash) >= 0)
+ && ((m_TokenIndex - numBackslash) <= m_BufferLen)
+ && (m_Buffer.GetChar(m_TokenIndex - numBackslash) == '\\') )
+ ++numBackslash;
+ if(numBackslash%2==1) // number of back slash(include current char ) is even
+ return true; // eg: "\""
+ else
+ return false; // eg: "\\""
+ }
+ return false;
}
Because my slow Internet,it seems a lot of messages were not caughted. :D
In this threadhttp://forums.codeblocks.org/index.php/topic,10990.msg75079.html#msg75079 (http://forums.codeblocks.org/index.php/topic,10990.msg75079.html#msg75079),the patch I provide is some kind of mistake.So please change it back.I test the codes,it can work under tktypedef,there are so many codes connect with tktypedef,it is risky to do this (apply this patch.)Thanks.
class sStruct
{
SomeClass* some_class;
int some_int;
void* some_void;
};
typedef class sStruct tStruct;
int main()
{
tStruct pp;
pp.
cout << "Hello world!" << endl;
return 0;
}
Index: parserthread.cpp
===================================================================
--- parserthread.cpp (revision 5730)
+++ parserthread.cpp (working copy)
@@ -1707,15 +1737,60 @@
#if PARSER_DEBUG_OUTPUT
Manager::Get()->GetLogManager()->DebugLog(F(_("Adding typedef: name='%s', ancestor='%s'"), components.front().c_str(), ancestor.c_str()));
#endif
- Token* tdef = DoAddToken(tkTypedef, components.front(), lineNr, 0, 0, args);
+ Token* tdef = DoAddToken(tkClass, components.front(), lineNr, 0, 0, args);
if (local_result.size() == 1)
{
int id = *local_result.begin();
Token* token = tree->at(id);
if (token->m_TokenKind == tkTypedef)
{
std::queue<ParserComponent> type_components;
BreakUpComponents(parser, token->m_ActualType, type_components);
while(!components.empty())
{
ParserComponent comp = components.front();
components.pop();
type_components.push(comp);
}
#ifdef DEBUG_CC_AI
if (s_DebugSmartSense)
#if wxCHECK_VERSION(2, 9, 0)
Manager::Get()->GetLogManager()->DebugLog(F(_T("Replacing %s to %s"), token->m_Name.wx_str(), token->m_ActualType.wx_str()));
#else
Manager::Get()->GetLogManager()->DebugLog(F(_T("Replacing %s to %s"), token->m_Name.c_str(), token->m_ActualType.c_str()));
#endif
#endif
return FindAIMatches(parser, type_components, result, parentTokenIdx, noPartialMatch, caseSensitive, use_inheritance, kindMask, search_scope);
}
}
#include <iostream>
using namespace std;
typedef class qq
{
int x;
int y;
}xx
int main()
{
cout << "Hello world!" << endl;
return 0;
}
Index: src/plugins/codecompletion/parser/parserthread.cpp
===================================================================
--- src/plugins/codecompletion/parser/parserthread.cpp (revision 5825)
+++ src/plugins/codecompletion/parser/parserthread.cpp (working copy)
@@ -1768,7 +1768,7 @@
Manager::Get()->GetLogManager()->DebugLog(F(_("HandleTypedef() : Adding typedef: name='%s', ancestor='%s'"), components.front().c_str(), ancestor.c_str()));
#endif
// Token* tdef = DoAddToken(tkTypedef, components.front(), lineNr, 0, 0, args);
- Token* tdef = DoAddToken(tkClass, components.front(), lineNr, 0, 0, args);
+ Token* tdef = DoAddToken(tkTypedef, components.front(), lineNr, 0, 0, args);
if (tdef)
{
if (!is_function_pointer)
@@ -1796,7 +1796,7 @@
m_Tokenizer.UngetToken();
break;
}
- else if (wxIsalpha(current.GetChar(0)))
+ else if (wxIsalpha(current.GetChar(0)) && (m_Tokenizer.PeekToken() == ParserConsts::semicolon || m_Tokenizer.PeekToken() == ParserConsts::comma))
{
#if PARSERTHREAD_DEBUG_OUTPUT
Manager::Get()->GetLogManager()->DebugLog(F(_T("ReadClsNames() : Adding variable '%s' as '%s' to '%s'"), current.c_str(), m_Str.c_str(), (m_pLastParent?m_pLastParent->m_Name.c_str():_T("<no-parent>"))));
@@ -1811,7 +1811,10 @@
}
}
- else // unexpected
+ else// unexpected
+ {
+ m_Tokenizer.UngetToken();
break;
+ }
}
}
Ok, tiny fixed with ReadClsNames in parserthread.
for broken codes below:Quote#include <iostream>
using namespace std;
typedef class qq
{
int x;
int y;
}xx
int main()
{
cout << "Hello world!" << endl;
return 0;
}
Exactly,but I refer to visual assist,its parser do what the patch do. :DI have applied your patch in my local copy, it works. :D. Thanks for your effort!
Token* tdef = DoAddToken(tkTypedef, components.front(), lineNr, 0, 0, args);
#include <iostream>
#include <iostream>
using namespace std;
std::vector<string> ssss;
#define xxxxxxxxx 12e
typedef class qq
{
int x;
int y;
}eeee;
typedef unsigned int wwwwwwwww;
www|
int main()
{
cout << "Hello world!" << endl;
return 0;
}
typedef unsigned int wwwwwwwww;
@blueshakeNice to hear that.Thanks. :D
That's something related in the nativeparser.cpp, and the code you cited. I will exam that. :D
typedef unsigned int wwwww;
wwww|
typedef class qq
{
int x;
int y;
}eeee;
if (local_result.size() == 1)
{
int id = *local_result.begin();
Token* token = tree->at(id);
if (token->m_TokenKind == tkTypedef)
{
std::queue<ParserComponent> type_components;
BreakUpComponents(parser, token->m_ActualType, type_components);
while(!components.empty())
{
ParserComponent comp = components.front();
components.pop();
type_components.push(comp);
}
#if DEBUG_CC_AI
if (s_DebugSmartSense)
#if wxCHECK_VERSION(2, 9, 0)
Manager::Get()->GetLogManager()->DebugLog(F(_T("Replacing %s to %s"), token->m_Name.wx_str(), token->m_ActualType.wx_str()));
#else
Manager::Get()->GetLogManager()->DebugLog(F(_T("Replacing %s to %s"), token->m_Name.c_str(), token->m_ActualType.c_str()));
#endif
#endif
return FindAIMatches(parser, type_components, result, parentTokenIdx, noPartialMatch, caseSensitive, use_inheritance, kindMask, search_scope);
}
}
www
CodeIndex: tokenizer.cpp
===================================================================
--- tokenizer.cpp (revision 5834)
+++ tokenizer.cpp (working copy)
@@ -216,17 +216,22 @@
bool Tokenizer::SkipToCharBreak()
{
- if (PreviousChar() != '\\')
- return true;
- else
- {
- // check for "\\"
- if ( ((m_TokenIndex - 2) >= 0)
- && ((m_TokenIndex - 2) <= m_BufferLen)
- && (m_Buffer.GetChar(m_TokenIndex - 2) == '\\') )
- return true;
- }
- return false;
+ if (PreviousChar() != '\\')
+ return true;
+ else
+ {
+ // check for "\\"
+ unsigned int numBackslash = 2;
+ while( ((m_TokenIndex - numBackslash) >= 0)
+ && ((m_TokenIndex - numBackslash) <= m_BufferLen)
+ && (m_Buffer.GetChar(m_TokenIndex - numBackslash) == '\\') )
+ ++numBackslash;
+ if(numBackslash%2==1) // number of back slash(include current char ) is even
+ return true; // eg: "\""
+ else
+ return false; // eg: "\\""
+ }
+ return false;
}
CodeIndex: src/plugins/codecompletion/parser/parserthread.cpp
===================================================================
--- src/plugins/codecompletion/parser/parserthread.cpp (revision 5825)
+++ src/plugins/codecompletion/parser/parserthread.cpp (working copy)
@@ -1768,7 +1768,7 @@
Manager::Get()->GetLogManager()->DebugLog(F(_("HandleTypedef() : Adding typedef: name='%s', ancestor='%s'"), components.front().c_str(), ancestor.c_str()));
#endif
// Token* tdef = DoAddToken(tkTypedef, components.front(), lineNr, 0, 0, args);
- Token* tdef = DoAddToken(tkClass, components.front(), lineNr, 0, 0, args);
+ Token* tdef = DoAddToken(tkTypedef, components.front(), lineNr, 0, 0, args);
if (tdef)
{
if (!is_function_pointer)
@@ -1796,7 +1796,7 @@
m_Tokenizer.UngetToken();
break;
}
- else if (wxIsalpha(current.GetChar(0)))
+ else if (wxIsalpha(current.GetChar(0)) && (m_Tokenizer.PeekToken() == ParserConsts::semicolon || m_Tokenizer.PeekToken() == ParserConsts::comma))
{
#if PARSERTHREAD_DEBUG_OUTPUT
Manager::Get()->GetLogManager()->DebugLog(F(_T("ReadClsNames() : Adding variable '%s' as '%s' to '%s'"), current.c_str(), m_Str.c_str(), (m_pLastParent?m_pLastParent->m_Name.c_str():_T("<no-parent>"))));
@@ -1811,7 +1811,10 @@
}
}
- else // unexpected
+ else// unexpected
+ {
+ m_Tokenizer.UngetToken();
break;
+ }
}
}
I think the function name "SkipToCharBreak" is confusion, because it doesn't really do a skip.That's right and probably was a typo. I'll change that certainly.
So, I suggest using another name like : IsRealCharBreak or IsCharBreak or IsEscapeChar
- Token* tdef = DoAddToken(tkClass, components.front(), lineNr, 0, 0, args);
+ Token* tdef = DoAddToken(tkTypedef, components.front(), lineNr, 0, 0, args);
// Remove duplicate items
for (size_t i=0; i<items.Count()-1; i++)
if (items.Item(i)==items.Item(i+1))
items.RemoveAt(i);
Manager::ge|
Manager::Get()->|
hello,another bad news.
It seems some bugs hide in the codecompletion.In the file codecompletion.cpp,in this place:Codewhen you type Mana,yes,the suggestion show,then you type ::,yes work again,but when you type ge,the issue come out,the suggestion list flash again,and not show.what is going on here,the suggestion list is try to show,but cancle by something.// Remove duplicate items
for (size_t i=0; i<items.Count()-1; i++)
if (items.Item(i)==items.Item(i+1))
items.RemoveAt(i);
Manager::ge|
Note:
I just use the latest cc,change nothing.
Edit:CodeAnd in the "|" position, the cc not work.Manager::Get()->|
#if PARSERTHREAD_DEBUG_OUTPUT
Manager::Get()->GetLogManager()->DebugLog(F(_T("HandlePreprocessorBlocks() : Special case \"#if 0\" not skipped.")));
#endif
#if PARSERTHREAD_DEBUG_OUTPUT
#define DebugOutput(a,b,c) Manager::Get()->GetLogManager()->DebugLog(a,b,c)
#else
#define DebugOutput(a,b,c)
#endif
DebugOutput(F(_T("HandlePreprocessorBlocks() : Special case \"#if 0\" not skipped.")));
Parser parser(this);
parser.ParseBufferForFunctions(control->GetTextRange(0, pos));
wxArrayString funcs;
TokensTree* tmptree = parser.GetTempTokens();
// look for implementation functions that enclose our current line number
for(size_t i = 0; i < tmptree->size();i++)
// find current function's namespace so we can include local scope's tokens
// we ' ll get the function's token (all matches) and add its parent namespace
TokenIdxSet scope_result;
TokenIdxSet proc_result;
if (FindCurrentFunctionToken(editor, proc_result) != 0)
{
for (TokenIdxSet::iterator it = proc_result.begin(); it != proc_result.end(); ++it)
{
Token* token = parser->GetTokens()->at(*it);
if (!token)
continue;
scope_result.insert(token->m_ParentIndex);
#if DEBUG_CC_AI
if (s_DebugSmartSense)
{
Token* parent = parser->GetTokens()->at(token->m_ParentIndex);
Manager::Get()->GetLogManager()->DebugLog(_T("Adding search namespace: ") + (parent ? parent->m_Name : _T("Global namespace")));
}
#endif
}
}
class DLLIMPORT Manager
{
static Manager* Get();
}
type is Manager *
actual type is Manager
@blueshake:But it worked before.I updated the local copy,and it don't work.
look at the Get function prototype, it is a static function.Codebut, in the symbol tree debug dialog, you will see that theclass DLLIMPORT Manager
{
static Manager* Get();
}Quotetype is Manager *
actual type is Manager
That's may be the cause of bug...
else if (token==ParserConsts::kw_static ||
token==ParserConsts::kw_virtual ||
token==ParserConsts::kw_inline)
{
// do nothing (skip it)
}
std::string ss;
ss. not work
string ss;
ss.work
string ss("abc");
ss.
@blueshake:But it worked before.I updated the local copy,and it don't work.
look at the Get function prototype, it is a static function.Codebut, in the symbol tree debug dialog, you will see that theclass DLLIMPORT Manager
{
static Manager* Get();
}Quotetype is Manager *
actual type is Manager
That's may be the cause of bug...
look at these codes.The static are ignored.Codeelse if (token==ParserConsts::kw_static ||
token==ParserConsts::kw_virtual ||
token==ParserConsts::kw_inline)
{
// do nothing (skip it)
}
Index: nativeparser.cpp
===================================================================
--- nativeparser.cpp (revision 5834)
+++ nativeparser.cpp (working copy)
@@ -1465,7 +1465,7 @@
tokenType = pttNamespace;
else
tokenType = pttClass;
- line.Remove(0, startAt + 2);
+ line.Remove(0, startAt + 1);
}
else
line.Clear();
Manager::Get()->
startAt = BeginOfToken(startAt, line);
// Check for [Class]. ('.' pressed)
if (IsOperatorDot(startAt, line))
{
--startAt;
repeat = true; // yes -> repeat.
}
// Check for [Class]-> ('>' pressed)
// Check for [Class]:: (':' pressed)
else if (IsOperatorEnd(startAt, line))
{
startAt -= 2;
repeat = true; // yes -> repeat.
}
I can confirm the issues I reported in reply 93,#99 can be fixed by ollydbg's #105 patch,even the tkTypedef can work too.I'm so grad to hear that!!!! :lol:
Hi
I found a issue.
if stest is a struct;
stest->b. ; //this is fail. Tip window can't pop up c
stest.b.c ; //this is ok .
typedef struct U_TKey{
int u32Key;
}U_KEYPAD_TWOKEY;
typedef struct S_KeyPad{
U_KEYPAD_TWOKEY unTKey;
void * pParam;
char u8CallBack_Type;
char u8DebounceClk;
char u8IntNum;
char u8TriggerType;
}S_KEYPAD_CLASS;
S_KEYPAD_CLASS sTest;
sTest.unTKey.u32Key=10;
S_KEYPAD_CLASS *psTest;
psTest->unTkey. // can't popup u32Key
S_KEYPAD_CLASS *psTest;
psTest->unTKey.
This works fine here:Code("u32Key" will be suggested).S_KEYPAD_CLASS *psTest;
psTest->unTKey.
...version, patform etc?
S_KEYPAD_CLASS *psTest;
psTest->unTkey. // can't popup u32Key
if (token->m_TokenKind == tkTypedef)
{
std::queue<ParserComponent> type_components;
BreakUpComponents(parser, token->m_ActualType, type_components);
while(!components.empty())
{
ParserComponent comp = components.front();
components.pop();
type_components.push(comp);
}
#if DEBUG_CC_AI
if (s_DebugSmartSense)
#if wxCHECK_VERSION(2, 9, 0)
Manager::Get()->GetLogManager()->DebugLog(F(_T("Replacing %s to %s"), token->m_Name.wx_str(), token->m_ActualType.wx_str()));
#else
Manager::Get()->GetLogManager()->DebugLog(F(_T("Replacing %s to %s"), token->m_Name.c_str(), token->m_ActualType.c_str()));
#endif
#endif
return FindAIMatches(parser, type_components, result, parentTokenIdx, noPartialMatch, caseSensitive, use_inheritance, kindMask, search_scope);
}
}
Work here,too.see the attachment.
Sorry to say that,but tktypedef don't work again.ollydbg is right,something is wrong with codes below,if I comment them,worked.!!!!!!!!Codeif (token->m_TokenKind == tkTypedef)
{
std::queue<ParserComponent> type_components;
BreakUpComponents(parser, token->m_ActualType, type_components);
while(!components.empty())
{
ParserComponent comp = components.front();
components.pop();
type_components.push(comp);
}
#if DEBUG_CC_AI
if (s_DebugSmartSense)
#if wxCHECK_VERSION(2, 9, 0)
Manager::Get()->GetLogManager()->DebugLog(F(_T("Replacing %s to %s"), token->m_Name.wx_str(), token->m_ActualType.wx_str()));
#else
Manager::Get()->GetLogManager()->DebugLog(F(_T("Replacing %s to %s"), token->m_Name.c_str(), token->m_ActualType.c_str()));
#endif
#endif
return FindAIMatches(parser, type_components, result, parentTokenIdx, noPartialMatch, caseSensitive, use_inheritance, kindMask, search_scope);
}
}
Sorry to say that,but tktypedef don't work again.ollydbg is right,something is wrong with codes below,if I comment them,worked.!!!!!!!!What does not work exactly? My test cases all work very well...?! Are you using latest SVN code?
Sorry to say that,but tktypedef don't work again.ollydbg is right,something is wrong with codes below,if I comment them,worked.!!!!!!!!What does not work exactly? My test cases all work very well...?! Are you using latest SVN code?
Sorry to say that,but tktypedef don't work again.ollydbg is right,something is wrong with codes below,if I comment them,worked.!!!!!!!!What does not work exactly? My test cases all work very well...?! Are you using latest SVN code?
failed when entering "wwww", there is a flash of the suggestion list.
(http://C:\Documents and Settings\Administrator\桌面\Snap5)confirmed. that's still something related to the source we mentioned in this thread.
See the pitcture,the wwwwwwwww value tip is wrong when I use tkTypedef.
It is strange.I just test the same codes in svn 5731,it worked.rev 5731 is before the cc_branch is merged. I'm just viewing the log Message of "nativeparser.cpp", and have a comparison with rev5682 of nativeparser.cpp.
Edit:
I guess maybe the BreakUpComponents function break down something.
if (local_result.size() == 1)
{
int id = *local_result.begin();
Token* token = tree->at(id);
if (token->m_TokenKind == tkTypedef)
{
std::queue<ParserComponent> type_components;
BreakUpComponents(parser, token->m_ActualType, type_components);
while(!components.empty())
{
ParserComponent comp = components.front();
components.pop();
type_components.push(comp);
}
#if DEBUG_CC_AI
if (s_DebugSmartSense)
#if wxCHECK_VERSION(2, 9, 0)
Manager::Get()->GetLogManager()->DebugLog(F(_T("FindAIMatches() : Replacing %s to %s"), token->m_Name.wx_str(), token->m_ActualType.wx_str()));
#else
Manager::Get()->GetLogManager()->DebugLog(F(_T("FindAIMatches() : Replacing %s to %s"), token->m_Name.c_str(), token->m_ActualType.c_str()));
#endif
#endif
return FindAIMatches(parser, type_components, result, parentTokenIdx, noPartialMatch, caseSensitive, use_inheritance, kindMask, search_scope);
}
}
if (event.GetEventType() == wxEVT_SCI_CHARADDED &&
!control->AutoCompActive()) { // not already active autocompletion
if (event.GetEventType() == wxEVT_SCI_CHARADDED)
what I have found is that these code:Codeif (local_result.size() == 1)
{
int id = *local_result.begin();
Token* token = tree->at(id);
if (token->m_TokenKind == tkTypedef)
{
std::queue<ParserComponent> type_components;
BreakUpComponents(parser, token->m_ActualType, type_components);
while(!components.empty())
{
ParserComponent comp = components.front();
components.pop();
type_components.push(comp);
}
#if DEBUG_CC_AI
if (s_DebugSmartSense)
#if wxCHECK_VERSION(2, 9, 0)
Manager::Get()->GetLogManager()->DebugLog(F(_T("FindAIMatches() : Replacing %s to %s"), token->m_Name.wx_str(), token->m_ActualType.wx_str()));
#else
Manager::Get()->GetLogManager()->DebugLog(F(_T("FindAIMatches() : Replacing %s to %s"), token->m_Name.c_str(), token->m_ActualType.c_str()));
#endif
#endif
return FindAIMatches(parser, type_components, result, parentTokenIdx, noPartialMatch, caseSensitive, use_inheritance, kindMask, search_scope);
}
}
Is added from rev 5682 to rev5840 of nativeparser.cpp.
#define TOKENIZER_DEBUG_OUTPUT 1
#if TOKENIZER_DEBUG_OUTPUT
#define TRACE(format, args...)\
Manager::Get()->GetLogManager()->DebugLog(F( format , ## args))
#else
#define TRACE(format, args...)
#endif
#if TOKENIZER_DEBUG_OUTPUT
Manager::Get()->GetLogManager()->DebugLog(F(_T("Init() : Called without filename.")));
#endif
TRACE(_T("Init() : Called without filename."));
#if TOKENIZER_DEBUG_OUTPUT
Manager::Get()->GetLogManager()->DebugLog(F(_T("Init() : m_Filename='%s'"), m_Filename.c_str()));
#endif
TRACE(_T("Init() : m_Filename='%s'"), m_Filename.c_str());
Sure this looks nice. But keep in mind that this should be in implementation files only, or rename TRACE into a more specific TRACE_NATIVEPARSER or alike. Otherwise you might define the macros also for other files (debug outputs). Patches against trunk are welcome.CodeAny comments? Thanks.#define TOKENIZER_DEBUG_OUTPUT 1
#if TOKENIZER_DEBUG_OUTPUT
#define TRACE(format, args...)\
Manager::Get()->GetLogManager()->DebugLog(F( format , ## args))
#else
#define TRACE(format, args...)
#endif
I would like Morten could give some explanation on the above two reply (reply#125, reply#126).I can't because I don't recall exactly. This code snippet was part of a patch that enabled parsing of typedefs correctly at all (it was not possible before). Probably it's obsolete now. I am testing CC without this snippet atm (you can do the same, if you like). If I don't see any issues I'll simply remove that portion.
By the way,how to insert a picture,not as a attachment. :?Google: image sharing site
Sure this looks nice. But keep in mind that this should be in implementation files only, or rename TRACE into a more specific TRACE_NATIVEPARSER or alike. Otherwise you might define the macros also for other files (debug outputs). Patches against trunk are welcome.CodeAny comments? Thanks.#define TOKENIZER_DEBUG_OUTPUT 1
#if TOKENIZER_DEBUG_OUTPUT
#define TRACE(format, args...)\
Manager::Get()->GetLogManager()->DebugLog(F( format , ## args))
#else
#define TRACE(format, args...)
#endif
__FUNCTION__
__PRETTY_FUNCTION__
I believe the std:: int the actualtype cause it.Guys, I found the reason for that and it's not easily solvable.
#ifndef _VECTOR_TCC
#define _VECTOR_TCC 1
namespace _GLIBCXX_STD
{
// ...
} // namespace std
#endif /* _VECTOR_TCC */
#ifndef _VECTOR_TCC
#define _VECTOR_TCC 1
_GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
// ...
_GLIBCXX_END_NESTED_NAMESPACE
#endif /* _VECTOR_TCC */
As we replace "_GLIBCXX_STD" within the parser with "std", std::(vector) was easily resolvable. Now things have changed for GCC4, now the wrapper is as follows:CodeAs you see: This is done using a macro. As we don't have macro expansion it won't work with out implementation of CC anymore. So - this is not a bug in CC, "just" a missing feature and it happens now as we all just jumped to GCC4.#ifndef _VECTOR_TCC
#define _VECTOR_TCC 1
_GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
// ...
_GLIBCXX_END_NESTED_NAMESPACE
#endif /* _VECTOR_TCC */
Hence I tried replacing:
_GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
with
using namespace std;
and:
_GLIBCXX_END_NESTED_NAMESPACE
with "empty", but this of course works not, too as the tokenizer has already tokenized the first statement. So the replacement cannot be done anymore. ;-)
We should expand the replacement method in tokenizer.cpp. :DNo. This does not work, because:
Hence I tried replacing:
_GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
with
using namespace std;
and:
_GLIBCXX_END_NESTED_NAMESPACE
with "empty", but this of course works not, too as the tokenizer has already tokenized the first statement. So the replacement cannot be done anymore. ;-)
We should expand the replacement method in tokenizer.cpp. :DNo. This does not work, because:Hence I tried replacing:
_GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
with
using namespace std;
and:
_GLIBCXX_END_NESTED_NAMESPACE
with "empty", but this of course works not, too as the tokenizer has already tokenized the first statement. So the replacement cannot be done anymore. ;-)
I mean, you can check the token == _GLIBCXX_BEGIN_NESTED_NAMESPACE, if it proves, the tokenizer can eat the following token which is ( "(std, _GLIBCXX_STD_D)"), or do anything you want.OK - that might work, indeed and would probably be a feasible solution. But: This is very error prone, for sure. If you look deeper into the STL classes the macros contain macros in itself so the order of replacements matters!
I mean, you can check the token == _GLIBCXX_BEGIN_NESTED_NAMESPACE, if it proves, the tokenizer can eat the following token which is ( "(std, _GLIBCXX_STD_D)"), or do anything you want.OK - that might work, indeed and would probably be a feasible solution. But: This is very error prone, for sure. If you look deeper into the STL classes the macros contain macros in itself so the order of replacements matters!
However - I did a nasty hack so that std:: completion works again. I am replacing directly within the buffer before the Tokenizer starts any action. This proves that CC would still be able to do the right thing so it's not a bug.
Hence the cost for this is several calls to wxString::Replace which simply takes an awful lot of time. But it was what I could do quickly.
If anybody is interested in a patch, I can so so...?!
If anybody is interested in a patch, I can so so...?!Here it is btw...
Morten can you sync trunk and debugger branch?Sure, but not today anymore.
Morten can you sync trunk and debugger branch?Done. Patch is not needed anymore, just uncomment the section in question in the tokenizer.
Index: src/plugins/codecompletion/parser/parserthread.cpp
===================================================================
--- src/plugins/codecompletion/parser/parserthread.cpp (revision 5852)
+++ src/plugins/codecompletion/parser/parserthread.cpp (working copy)
@@ -1765,6 +1765,7 @@
{
tdef->m_AncestorsString = ancestor;
tdef->m_ActualType = ancestor;
+ tdef->m_Type = ancestor;
}
else
tdef->m_ActualType = ancestor + args;
For the right valuetip on typedef.
patch:CodeIndex: src/plugins/codecompletion/parser/parserthread.cpp
===================================================================
--- src/plugins/codecompletion/parser/parserthread.cpp (revision 5852)
+++ src/plugins/codecompletion/parser/parserthread.cpp (working copy)
@@ -1765,6 +1765,7 @@
{
tdef->m_AncestorsString = ancestor;
tdef->m_ActualType = ancestor;
+ tdef->m_Type = ancestor;
}
else
tdef->m_ActualType = ancestor + args;
#include <iostream>
#include <iostream>
using namespace std;
std::vector<string> ssss;
#define xxxxxxxxx 12e
typedef class qq
{
int x;
int y;
}eeee;
typedef unsigned int wwwwwwwww;
www!
int main()
{
cout << "Hello world!" << endl;
return 0;
}
#include <iostream>
using namespace std;
struct qq
{
int x;
int y;
};
typedef qq (*ptr)(int a, int b);
ptr pp;
pp(3,3). --------not work.
int main()
{
cout << "Hello world!" << endl;
return 0;
}
if (token.GetChar(0) == '(')
{
// function pointer (probably)
is_function_pointer = true;
if (peek.GetChar(0) == '(')
{
// typedef void (*dMessageFunction)(int errnum, const char *msg, va_list ap);
// typedef void (MyClass::*Function)(int);
// remove parentheses and keep everything after the dereferencing symbol
token.RemoveLast();
int pos = token.Find('*', true);
if (pos != wxNOT_FOUND)
{
typ << _T('(') << token.Mid(1, pos) << _T(')');
token.Remove(0, pos + 1);
}
else
{
typ = _T("(*)");
token.Remove(0, 1); // remove opening parenthesis
}
args = peek;
components.push(token);
}
else
{
// typedef void dMessageFunction (int errnum, const char *msg, va_list ap);
typ = _T("(*)");
// last component is already the name and this is the args
args = token;
}
break;
}
typedef qq (*ptr)(int a, int b);
ptr pp;
pp(3,3). --------not work.
typedef qq (*ptr)(int a, int b);
typedef qq ptr;
Dear ollydbg,Good idea, I will try it :D.
I think the actualtype should be qq,and the type should be qq(*), and the ancestor should be qq too,
for codes:Codecan be treat astypedef qq (*ptr)(int a, int b);
Codeand this maybe can fix the bug.typedef qq ptr;
Index: src/plugins/codecompletion/parser/token.cpp
===================================================================
--- src/plugins/codecompletion/parser/token.cpp (revision 5852)
+++ src/plugins/codecompletion/parser/token.cpp (working copy)
@@ -126,15 +126,42 @@
wxString Token::DisplayName() const
{
-// wxString result(_T(""));
-// wxString parentname = GetParentName();
-// if (!parentname.IsEmpty())
-// result << parentname << _T("::");
- wxString result = GetNamespace();
- result << m_Name << m_Args;
- if (!m_Type.IsEmpty())
- result << _T(" : ") << m_Type;
- return result;
+ wxString result;
+ if (m_TokenKind == tkClass)
+ {
+ result << _T("class ") << m_Name << _T(" {...}");
+ return result;
+ }
+ else if (m_TokenKind == tkNamespace)
+ {
+ result << _T("namespace ") << m_Name << _T(" {...}");
+ return result;
+ }
+ else if (m_TokenKind == tkEnum)
+ {
+ return result << _T("enum ") << m_Name << _T(" {...}");
+ }
+ else if (m_TokenKind == tkTypedef)
+ {
+ result << _T("typedef") ;
+ if (!m_Type.IsEmpty())
+ result << _T(" ") << m_Type;
+ result << _T(" ") << m_Name;
+ return result;
+ }
+ else if (m_TokenKind == tkPreprocessor)
+ {
+ result << _T("#define ") << m_Name << m_Args;
+ if(!m_Type.IsEmpty())
+ result << _T(" ") << m_Type;
+ return result;
+ }
+ else
+ {
+ if (!m_Type.IsEmpty())
+ result << m_Type << _T(" ");
+ return result << GetNamespace() << m_Name << m_Args;
+ }
}
Token* Token::GetParentToken()
int bbbbb(int cccccc)
{
//can't pop up cccccc
}
Hi,
In SVN 5840, code completion can pop up function paramter.
But SVN 5853, it's not.
What happen ? or do I some error thing ? :(Code
int bbbbb(int cccccc)
{
//can't pop up cccccc
}
// Start an Artificial Intelligence (!) sequence to gather all the matching tokens..
// The actual AI is in FindAIMatches() below...
size_t NativeParser::AI(TokenIdxSet& result,
cbEditor* editor,
Parser* parser,
const wxString& lineText,
bool noPartialMatch,
bool caseSensitive,
TokenIdxSet* search_scope,
int caretPos)
void zfunction(int abcdefg){
ab| <---
;
};
if (items.GetCount() == 0)
return -2;
Dear ollydbg:
The function tokens search followed the below steps:
1.serach the function name the line stayed.
2.parse the function arguments and stored tokens in pTempTree.
3.parse the fucntion body and stored tokens in pTempTree.
I guess we should check whether tokens(e.g. ccccc) in the pTempTree, and make sure the pTempTree is searched.
should compare with last svn version,I guess it caused by the recent fixed.
I can confirm it work in svn 5852.
see my screen shot.
if (!token->m_Args.IsEmpty() && !token->m_Args.Matches(_T("()")))
{
wxString buffer = token->m_Args;
buffer.Remove(0, 1); // remove (
buffer.RemoveLast(); // remove )
buffer.Replace(_T(","), _T(";")); // replace commas with semi-colons
buffer << _T(';'); // aid parser ;)
buffer.Trim();
if (s_DebugSmartSense)
{
#if wxCHECK_VERSION(2, 9, 0)
Manager::Get()->GetLogManager()->DebugLog(F(_T("Parsing arguments: \"%s\""), buffer.wx_str()));
#else
Manager::Get()->GetLogManager()->DebugLog(F(_T("Parsing arguments: \"%s\""), buffer.c_str()));
#endif
if (!buffer.IsEmpty() && !parser->ParseBuffer(buffer, false, false, true))
{
Manager::Get()->GetLogManager()->DebugLog(_T("ERROR parsing arguments"));
}
}
I'm sorry, I find the bug, it's here...so?! What exactly is wrong with that portion?
line 766-787 of nativeparser.cpp.
I'm sorry, I find the bug, it's here...so?! What exactly is wrong with that portion?
line 766-787 of nativeparser.cpp.
The code is wrapped in the if (s_DebugSmartSense )from rev 5840 to 5845 of the nativeparser.cpp.Argh! Good one. Nevermind... my mistake. :oops: I was always using it *with* DebugSmartSense enabled, so that's why it worked here... Will commit the fix soon...
The code is wrapped in the if (s_DebugSmartSense )from rev 5840 to 5845 of the nativeparser.cpp.Argh! Good one. Nevermind... my mistake. :oops: I was always using it *with* DebugSmartSense enabled, so that's why it worked here... Will commit the fix soon...
Will commit the fix soon......done.
Look so good.Will commit the fix soon......done.
:lol: :lol: :lol: :lol: :lol: :lol: :lol: :lol:Will commit the fix soon......done.
struct _s
{
int x;
float y;
};
typedef struct _s t_s;
typedef struct _s_inner
{
int z_inner;
} t_s_inner;
Quick question... in the structs_typedefs.cpp (from the tests - thx Morten):Codestruct _s
{
int x;
float y;
};
typedef struct _s t_s;
typedef struct _s_inner
{
int z_inner;
} t_s_inner;
C::B shows "t_s" as a typedef, BUT "t_s_inner" as a class. Is this a bug or a feature? :D
Btw, I was expecting to see "t_s_inner" as a typedef... ;)
daniloz
PS: why are structs treated as class by the CC?
Quick question... in the structs_typedefs.cpp (from the tests - thx Morten):Codestruct _s
{
int x;
float y;
};
typedef struct _s t_s;
typedef struct _s_inner
{
int z_inner;
} t_s_inner;
C::B shows "t_s" as a typedef, BUT "t_s_inner" as a class. Is this a bug or a feature? :D
Btw, I was expecting to see "t_s_inner" as a typedef... ;)
daniloz
PS: why are structs treated as class by the CC?
struct _s
{
int x;
float y;
};
typedef struct _s t_s;
typedef t_s ssss;
ssss.
Index: src/plugins/codecompletion/parser/parserthread.cpp
===================================================================
--- src/plugins/codecompletion/parser/parserthread.cpp (revision 5859)
+++ src/plugins/codecompletion/parser/parserthread.cpp (working copy)
@@ -1795,13 +1795,15 @@
current.c_str(),
m_Str.c_str(),
(m_pLastParent ? m_pLastParent->m_Name.c_str():_T("<no-parent>")));
- Token* newToken = DoAddToken(tkClass, current, m_Tokenizer.GetLineNumber());
+ Token* newToken = DoAddToken(tkTypedef, current, m_Tokenizer.GetLineNumber());
if (!newToken)
break;
else
{
wxString tempAncestor = ancestor;
newToken->m_AncestorsString = tempAncestor;
+ newToken->m_ActualType = tempAncestor;
+ newToken->m_Type = tempAncestor;
}
}
else // unexpected
Index: src/plugins/codecompletion/parser/token.cpp
===================================================================
--- src/plugins/codecompletion/parser/token.cpp (revision 5859)
+++ src/plugins/codecompletion/parser/token.cpp (working copy)
@@ -865,7 +865,7 @@
{
Token* ancestorToken = at(*it);
// only classes take part in inheritance
- if (ancestorToken && ancestorToken != token && (ancestorToken->m_TokenKind == tkClass || ancestorToken->m_TokenKind == tkEnum))// && !ancestorToken->m_IsTypedef)
+ if (ancestorToken && ancestorToken != token && (ancestorToken->m_TokenKind == tkClass || ancestorToken->m_TokenKind == tkEnum || ancestorToken->m_TokenKind == tkTypedef))// && !ancestorToken->m_IsTypedef)
{
token->m_Ancestors.insert(*it);
ancestorToken->m_Descendants.insert(i);
// t_ptr.
// t_ptr(3,3).
// t_ptr_s(
// t_ptr_s(3,3).
<TOKEN_REPLACEMENTS>
<ssmap>
<_GLIBCXX_BEGIN_NAMESPACE>
<![CDATA[+namespace]]>
</_GLIBCXX_BEGIN_NAMESPACE>
<_GLIBCXX_BEGIN_NAMESPACE_TR1>
<![CDATA[-namespace tr1 {]]>
</_GLIBCXX_BEGIN_NAMESPACE_TR1>
<_GLIBCXX_BEGIN_NESTED_NAMESPACE>
<![CDATA[+namespace]]>
</_GLIBCXX_BEGIN_NESTED_NAMESPACE>
<_GLIBCXX_END_NAMESPACE>
<![CDATA[}]]>
</_GLIBCXX_END_NAMESPACE>
<_GLIBCXX_END_NAMESPACE_TR1>
<![CDATA[}]]>
</_GLIBCXX_END_NAMESPACE_TR1>
<_GLIBCXX_END_NESTED_NAMESPACE>
<![CDATA[}]]>
</_GLIBCXX_END_NESTED_NAMESPACE>
<_GLIBCXX_STD>
<![CDATA[std]]>
</_GLIBCXX_STD>
</ssmap>
</TOKEN_REPLACEMENTS>
What I want to know is if doing this wil slow down the parse process?
void ClassBrowser::UpdateView()
{
m_pActiveProject = 0;
m_ActiveFilename.Clear();
if (m_pParser && !Manager::IsAppShuttingDown())
{
m_pActiveProject = Manager::Get()->GetProjectManager()->GetActiveProject();
cbEditor* ed = Manager::Get()->GetEditorManager()->GetBuiltinActiveEditor();
if (ed)
{
//m_ActiveFilename = ed->GetFilename().BeforeLast(_T('.'));
// the above line is a bug (see https://developer.berlios.de/patch/index.php?func=detailpatch&patch_id=1559&group_id=5358)
m_ActiveFilename = ed->GetFilename().AfterLast(wxFILE_SEP_PATH);
if( m_ActiveFilename.Find(_T('.')) != wxNOT_FOUND )
{
m_ActiveFilename = ed->GetFilename().BeforeLast(wxFILE_SEP_PATH) + wxFILE_SEP_PATH + m_ActiveFilename.BeforeLast(_T('.'));
m_ActiveFilename.Append(_T('.'));
}
else
m_ActiveFilename = ed->GetFilename();
}
BuildTree();
wxSplitterWindow* splitter = XRCCTRL(*this, "splitterWin", wxSplitterWindow);
if (m_pParser->ClassBrowserOptions().treeMembers)
{
splitter->SplitHorizontally(m_Tree, m_TreeBottom);
m_TreeBottom->Show(true);
}
else
{
splitter->Unsplit();
m_TreeBottom->Show(false);
}
}
else
m_Tree->DeleteAllItems();
}
bool Tokenizer::SkipComment(bool skipEndWhite)
{
bool cstyle; // C or C++ style comments
//check the comment prompt
if(CurrentChar() == '/')
{
if(NextChar() == '*')
cstyle = true;
else if(NextChar() == '/')
cstyle = false;
else
return true; //Not the comment prompt, return true;
}
else
return true; //Not the comment prompt, return true;
MoveToNextChar(2); //skip the comment prompt
while(true)
{
if (cstyle) //c style comment
{
SkipToChar('/');
if (PreviousChar() == '*')//the end of C style comments
{
MoveToNextChar();
break;
}
if(!MoveToNextChar())
break;
}
else //c++ style comment
{
SkipToEOL(false, true);//nestBrace = false skipcomment = true
MoveToNextChar();
break;
}
}
if (IsEOF())
return false;
if (skipEndWhite)
{
if(!SkipWhiteSpace())
return false;
}
else
return true;
return SkipComment(); // handle chained comments
}
if ( m_LastWasPreprocessor
&& !str.IsSameAs(_T("#"))
&& !m_LastPreprocessor.IsSameAs(_T("#")) )
{
if (!m_LastPreprocessor.IsSameAs(TokenizerConsts::include_str))
{
// except for #include and #if[[n]def], all other preprocessor directives need only
// one word exactly after the directive, e.g. #define THIS_WORD
SkipToEOL();
}
m_LastPreprocessor.Clear();
}
bool MoveToNextChar(const unsigned int amount = 1)
{
assert(amount);
if(amount == 1) // compiler will dead-strip this
{
++m_TokenIndex;
if (IsEOF())
{
m_TokenIndex = m_BufferLen;
return false;
}
if (CurrentChar() == _T('\n'))
++m_LineNumber;
return true;
}
else
{
m_TokenIndex += amount;
if (IsEOF())
{
m_TokenIndex = m_BufferLen;
return false;
}
if (CurrentChar() == _T('\n'))
++m_LineNumber;
return true;
}
};
wxChar CurrentChar() const
{
if(m_TokenIndex < m_BufferLen)
return m_Buffer.GetChar(m_TokenIndex);
return 0;
};
Parsing stage done (1511 total parsed files, 84442 tokens in 0 minute(s), 12.468 seconds)....did you notice? That's weired.
after patch
Parsing stage done (1510 total parsed files, 84506 tokens in 0 minute(s), 12.578 seconds).
1. In Tokenizer.cpp. the if condition never be true in the DoGetToken function...which one (which if condition) you mean? For me both still make sense...?!
[...]
So, these code can be deleted.
2, I tokenizer.h think in the CurrentChar function, we don't need to check index value, because MoveToNextChar already do this.That's true, but I wanted to avoid any issues with API mis-use (meaning calling CurrentChar() before MoveToNextChar() for any obscure reason). I wonder what this would differ in terms of time. Implementing a temporary time measurement would reveal the difference.
Yes, it is weird. I don't know why...Parsing stage done (1511 total parsed files, 84442 tokens in 0 minute(s), 12.468 seconds)....did you notice? That's weird.
after patch
Parsing stage done (1510 total parsed files, 84506 tokens in 0 minute(s), 12.578 seconds).
1. In Tokenizer.cpp. the if condition never be true in the DoGetToken function...which one (which if condition) you mean? For me both still make sense...?!
[...]
So, these code can be deleted.
bool Tokenizer::SkipUnwanted()
{
while (CurrentChar() == '#' ||
(!m_IsOperator && CurrentChar() == '=') ||
(!m_IsOperator && CurrentChar() == '[') ||
CurrentChar() == '?' ||
(CurrentChar() == '/' && (NextChar() == '/' || NextChar() == '*') ))
{
bool skipPreprocessor = false; // used for #include
while (m_Buffer.Mid(m_TokenIndex, 2) == _T("//") ||
m_Buffer.Mid(m_TokenIndex, 2) == _T("/*"))
{
// C/C++ style comments
SkipComment();
if (IsEOF())
return false;
if (!SkipWhiteSpace())
return false;
}
while (CurrentChar() == '#')
{
// preprocessor directives
// we only care for #include and #define, for now
unsigned int backupIdx = m_TokenIndex;
MoveToNextChar();
SkipWhiteSpace();
if ((CurrentChar() == 'i' && NextChar() == 'n') || // in(clude)
(CurrentChar() == 'i' && NextChar() == 'f') || // if(|def|ndef)
(CurrentChar() == 'e' && NextChar() == 'l') || // el(se|if)
(CurrentChar() == 'e' && NextChar() == 'n') || // en(dif)
(m_TokenizerOptions.wantPreprocessor && CurrentChar() == 'd' && NextChar() == 'e')) // de(fine)
{
// ok, we have something like #in(clude)
m_LastWasPreprocessor = true;
m_LastPreprocessor.Clear();
m_TokenIndex = backupIdx; // keep #
skipPreprocessor = true;
break;
}
I has discussed this with blueshake, he can confirm this. That's because in the logic bug in SkipUnwanted.So... now you got me a little confused (or probably it's too early for me). So you propose to remove the "if" conditions because of a bug in SkipUnwanted? Shouldn't we better fix the bug? And then: Where exactly is the bug in the code snippet?
see the code:
I has discussed this with blueshake, he can confirm this. That's because in the logic bug in SkipUnwanted.So... now you got me a little confused (or probably it's too early for me). So you propose to remove the "if" conditions because of a bug in SkipUnwanted? Shouldn't we better fix the bug? And then: Where exactly is the bug in the code snippet?
see the code:
Could you do me a favour and comment the lines / snippets in question in the code you've posted? That'll help me a lot. Please explain a little more... :(
if ( m_LastWasPreprocessor
&& !str.IsSameAs(_T("#"))
&& !m_LastPreprocessor.IsSameAs(_T("#")) )
{
if (!m_LastPreprocessor.IsSameAs(TokenizerConsts::include_str))
{
// except for #include and #if[[n]def], all other preprocessor directives need only
// one word exactly after the directive, e.g. #define THIS_WORD
SkipToEOL();
}
m_LastPreprocessor.Clear();
}
if (m_LastWasPreprocessor)
m_LastPreprocessor << str;
m_LastWasPreprocessor = false;
return str;
if ((CurrentChar() == 'i' && NextChar() == 'n') || // in(clude)
(CurrentChar() == 'i' && NextChar() == 'f') || // if(|def|ndef)
(CurrentChar() == 'e' && NextChar() == 'l') || // el(se|if)
(CurrentChar() == 'e' && NextChar() == 'n') || // en(dif)
(m_TokenizerOptions.wantPreprocessor && CurrentChar() == 'd' && NextChar() == 'e')) // de(fine)
{
// ok, we have something like #in(clude)
m_LastWasPreprocessor = true;
m_LastPreprocessor.Clear();
m_TokenIndex = backupIdx; // keep #
skipPreprocessor = true;
break;
}
else
what more I want to say is the logical error:Hi, blueshake, Thanks for the explanation. :D.
The only chance the variable m_LastWasPreprocessor becomes true is in these codes:Codeif ((CurrentChar() == 'i' && NextChar() == 'n') || // in(clude)
(CurrentChar() == 'i' && NextChar() == 'f') || // if(|def|ndef)
(CurrentChar() == 'e' && NextChar() == 'l') || // el(se|if)
(CurrentChar() == 'e' && NextChar() == 'n') || // en(dif)
(m_TokenizerOptions.wantPreprocessor && CurrentChar() == 'd' && NextChar() == 'e')) // de(fine)
{
// ok, we have something like #in(clude)
m_LastWasPreprocessor = true;
m_LastPreprocessor.Clear();
m_TokenIndex = backupIdx; // keep #
skipPreprocessor = true;
break;
}
else
at this time,str contain the string "#",and m_LastPreprocessor is empty.(see codes above)
so the three conditions in if:
m_LastWasPreprocessor------------------------true
!str.IsSameAs(_T("#"))-------------------------false
!m_LastPreprocessor.IsSameAs(_T("#"))-------true
see ,the three conditions can not all be true at the same time.It means the "if " condition can never be true.
m_LastWasPreprocessor------------------------trueCould it be that simply the "!str..." line should be removed as it is a relict of old times???
!str.IsSameAs(_T("#"))-------------------------false
!m_LastPreprocessor.IsSameAs(_T("#"))-------true
if ((CurrentChar() == 'i' && NextChar() == 'n') || // in(clude)
(CurrentChar() == 'i' && NextChar() == 'f') || // if(|def|ndef)
(CurrentChar() == 'e' && NextChar() == 'l') || // el(se|if)
(CurrentChar() == 'e' && NextChar() == 'n') || // en(dif)
(m_TokenizerOptions.wantPreprocessor && CurrentChar() == 'd' && NextChar() == 'e')) // de(fine)
{
// ok, we have something like #in(clude)
m_LastWasPreprocessor = true;
m_LastPreprocessor.Clear();
m_TokenIndex = backupIdx; // keep #
skipPreprocessor = true;
break;
}
else
else if (token==ParserConsts::hash)
{
token = m_Tokenizer.GetToken();
if (token==ParserConsts::kw_include)
HandleIncludes();
else if (token==ParserConsts::kw_define)
HandleDefines();
else
HandlePreprocessorBlocks(token);
m_Str.Clear();
}
void ParserThread::HandlePreprocessorBlocks(const wxString& preproc)
{
if (preproc.StartsWith(ParserConsts::kw_if)) // #if, #ifdef, #ifndef
{
wxString token = preproc;
++m_PreprocessorIfCount;
token = m_Tokenizer.GetToken();
if (token.IsSameAs(_T("0")))
{
// TODO: handle special case "#if 0"
TRACE(_T("HandlePreprocessorBlocks() : Special case \"#if 0\" not skipped."));
}
m_Tokenizer.SkipToEOL();
}
else if (preproc==ParserConsts::kw_else || preproc==ParserConsts::kw_elif) // #else, #elif
{
TRACE(_T("HandlePreprocessorBlocks() : Saving nesting level: %d"), m_Tokenizer.GetNestingLevel());
m_Tokenizer.SaveNestingLevel();
wxString token = preproc;
while (!token.IsEmpty() && token != ParserConsts::kw_endif)
token = m_Tokenizer.GetToken();
--m_PreprocessorIfCount;
#if PARSERTHREAD_DEBUG_OUTPUT
int l = m_Tokenizer.GetNestingLevel();
#endif
m_Tokenizer.RestoreNestingLevel();
TRACE(_T("HandlePreprocessorBlocks() : Restoring nesting level: %d (was %d)"), m_Tokenizer.GetNestingLevel(), l);
}
else if (preproc==ParserConsts::kw_endif) // #endif
--m_PreprocessorIfCount;
}
Notice that there is another call to HandlePreprocessorBlocks() in void ParserThread::SkipBlock() and ParserThread::HandleClass(EClassType ct).Codeelse if (token==ParserConsts::hash)
{
token = m_Tokenizer.GetToken();
if (token==ParserConsts::kw_include)
HandleIncludes();
else if (token==ParserConsts::kw_define)
HandleDefines();
else
HandlePreprocessorBlocks(token);
m_Str.Clear();
}
Notice that there is another call to HandlePreprocessorBlocks() in void ParserThread::SkipBlock() and ParserThread::HandleClass(EClassType ct).I've added a test case for pre-processor handling to trunk. You'll realise that a lot things are not (yet) working (check the symbols browser). A major bug is handling of comments in preprocessors. :-(
I've added a test case for pre-processor handling to trunk. You'll realise that a lot things are not (yet) working (check the symbols browser). A major bug is handling of comments in preprocessors. :-(hello,morten
Notice that there is another call to HandlePreprocessorBlocks() in void ParserThread::SkipBlock() and ParserThread::HandleClass(EClassType ct).Codeelse if (token==ParserConsts::hash)
{
token = m_Tokenizer.GetToken();
if (token==ParserConsts::kw_include)
HandleIncludes();
else if (token==ParserConsts::kw_define)
HandleDefines();
else
HandlePreprocessorBlocks(token);
m_Str.Clear();
}
#pragma XXXX
Feed back and test case are all welcome!!! :DI cannot apply this patch on trunk. Could you please provide a patch against (current) trunk using svn diff?
Feed back and test case are all welcome!!! :DI cannot apply this patch on trunk. Could you please provide a patch against (current) trunk using svn diff?
Sorry, I don't know how to use svn diff. :oops:It's very easy:
So, I upload the source file for you, :DWorks, thanks! I'll have a look... I have pending quite some patches now...
Thanks for your help!!Sorry, I don't know how to use svn diff. :oops:It's very easy:
- Install the SVN command lien client
- Modify the sources as needed
- Within the SVN controlled (sub-)directory, issue this command:
svn diff > my_patch.patch
Done. :-)
- Within the SVN controlled (sub-)directory, issue this command:
svn diff > my_patch.patch
Done. :-)
Within the root of the svn tree is the better place to issue the command (also svn help diff for more info)Not for me, as I don't checkout the whole sources usually. So I need to manually change the patch quite often to remove e.g. the top-level "src" folder. Just do it as you like, I can handle both.
Index: parserthread.cpp
===================================================================
--- parserthread.cpp (revision 5872)
+++ parserthread.cpp (working copy)
@@ -1719,7 +1719,7 @@
{
// typedef void dMessageFunction (int errnum, const char *msg, va_list ap);
- typ = _T("(*)");
+ //typ = _T("(*)");
// last component is already the name and this is the args
args = token;
}
@@ -1757,7 +1757,7 @@
ancestor << _T(' ');
ancestor << token;
}
- ancestor << typ;
+ //ancestor << typ;
// no return type
m_Str.Clear();
@@ -1773,7 +1773,12 @@
tdef->m_Type = ancestor;
}
else
- tdef->m_ActualType = ancestor + args;
+ {
+ tdef->m_ActualType = ancestor;
+ tdef->m_Type = ancestor + typ;//+ args;
+ tdef->m_AncestorsString = ancestor;
+ }
+
}
}
@@ -1800,13 +1805,15 @@
current.c_str(),
m_Str.c_str(),
(m_pLastParent ? m_pLastParent->m_Name.c_str():_T("<no-parent>")));
- Token* newToken = DoAddToken(tkClass, current, m_Tokenizer.GetLineNumber());
+ Token* newToken = DoAddToken(tkTypedef, current, m_Tokenizer.GetLineNumber());
if (!newToken)
break;
else
{
wxString tempAncestor = ancestor;
newToken->m_AncestorsString = tempAncestor;
+ newToken->m_ActualType = tempAncestor;
+ newToken->m_Type = tempAncestor;
}
}
else // unexpected
Index: token.cpp
===================================================================
--- token.cpp (revision 5872)
+++ token.cpp (working copy)
@@ -138,13 +138,11 @@
wxString result;
if (m_TokenKind == tkClass)
{
- result << _T("class ") << m_Name << _T(" {...}");
- return result;
+ return result << _T("class ") << m_Name << _T(" {...}");
}
else if (m_TokenKind == tkNamespace)
{
- result << _T("namespace ") << m_Name << _T(" {...}");
- return result;
+ return result << _T("namespace ") << m_Name << _T(" {...}");
}
else if (m_TokenKind == tkEnum)
{
@@ -155,15 +153,18 @@
result << _T("typedef") ;
if (!m_Type.IsEmpty())
result << _T(" ") << m_Type;
- result << _T(" ") << m_Name;
- return result;
+ if (result.find('*', true) != wxNOT_FOUND)
+ {
+ result.RemoveLast();
+ return result << m_Name << _T(")") << m_Args;
+ }
+ return result << _T(" ") << m_Name;
}
else if (m_TokenKind == tkPreprocessor)
{
result << _T("#define ") << m_Name << m_Args;
if(!m_Type.IsEmpty())
- result << _T(" ") << m_Type;
- return result;
+ return result << _T(" ") << m_Type;
}
else
{
a b::c d::e() {;};
Index: structs_typedefs.cpp
===================================================================
--- structs_typedefs.cpp (revision 5873)
+++ structs_typedefs.cpp (working copy)
@@ -6,7 +6,7 @@
float y;
};
typedef struct _s t_s;
-typedef _s (*t_ptr)(int a, int b);
+typedef _s (*t_ptr_s)(int a, int b);
typedef struct _s_inner
{
void ClassBrowser::UpdateView()
{
m_pActiveProject = 0;
m_ActiveFilename.Clear();
if (m_pParser && !Manager::IsAppShuttingDown())
{
m_pActiveProject = Manager::Get()->GetProjectManager()->GetActiveProject();
cbEditor* ed = Manager::Get()->GetEditorManager()->GetBuiltinActiveEditor();
if (ed)
{
//m_ActiveFilename = ed->GetFilename().BeforeLast(_T('.'));
// the above line is a bug (see https://developer.berlios.de/patch/index.php?func=detailpatch&patch_id=1559&group_id=5358)
m_ActiveFilename = ed->GetFilename().AfterLast(wxFILE_SEP_PATH);
if (m_ActiveFilename.Find(_T('.')) != wxNOT_FOUND)
{
m_ActiveFilename = ed->GetFilename().BeforeLast(wxFILE_SEP_PATH) + wxFILE_SEP_PATH + m_ActiveFilename.BeforeLast(_T('.'));
m_ActiveFilename.Append(_T('.'));
}
else
m_ActiveFilename = ed->GetFilename();
}
BuildTree();
wxSplitterWindow* splitter = XRCCTRL(*this, "splitterWin", wxSplitterWindow);
if (m_pParser->ClassBrowserOptions().treeMembers)
{
splitter->SplitHorizontally(m_Tree, m_TreeBottom);
m_TreeBottom->Show(true);
}
else
{
splitter->Unsplit();
m_TreeBottom->Show(false);
}
}
else
m_Tree->DeleteAllItems();
}
At this time, we don't need to rebuild the tree again.hi,ollydbg:
At this time, we get the same browser tree, if you select "current file's token" in browser view.QuoteAt this time, we don't need to rebuild the tree again.hi,ollydbg:
The contexts in C:\BBB\AAA.cpp are different from C:\BBB\AAA.h,why we don't need to rebuild the tree again?
#include <iostream>
using namespace std;
int variableA;
int main()
{
int variableA;
variableA = 1;
cout << "Hello world!" << endl;
return 0;
}
Hm, Olly having both in the tooltip can be quite helpful.should be easy to do this.
If for example the tooltip looks like this:
global int variableA
local int variableA
or
int ::variableA
int variableA
int my_namespace::variableA
Hm, Olly having both in the tooltip can be quite helpful.
If for example the tooltip looks like this:
global int variableA
local int variableA
or
int ::variableA
int variableA
int my_namespace::variableA
Index: src/plugins/codecompletion/parser/token.cpp
===================================================================
--- src/plugins/codecompletion/parser/token.cpp (revision 5894)
+++ src/plugins/codecompletion/parser/token.cpp (working copy)
@@ -136,6 +136,10 @@
wxString Token::DisplayName() const
{
wxString result;
+ if (m_IsTemp)
+ result << _T("local ");
+ else
+ result << _T("global ");
if (m_TokenKind == tkClass)
return result << _T("class ") << m_Name << _T(" {...}");
else if (m_TokenKind == tkNamespace)
bool NativeParser::ParseLocalBlock(cbEditor* ed, int caretPos)
{
if (!ed)
return false;
Parser* parser = FindParserFromEditor(ed);
if (!parser)
return false;
if (!parser->Done())
return false;
if (s_DebugSmartSense)
Manager::Get()->GetLogManager()->DebugLog(_T("Parse local block"));
int blockStart = FindCurrentFunctionStart(ed, 0, 0, caretPos);
if (blockStart != -1)
{
++blockStart; // skip {
int blockEnd = caretPos == -1 ? ed->GetControl()->GetCurrentPos() : caretPos;
if (blockEnd < 0 || blockEnd > ed->GetControl()->GetLength())
return false;
if (blockStart >= blockEnd)
blockStart = blockEnd;
wxString buffer = ed->GetControl()->GetTextRange(blockStart, blockEnd);
buffer.Trim();
if (!buffer.IsEmpty() && !parser->ParseBuffer(buffer, false, false, true))
{
if (s_DebugSmartSense)
Manager::Get()->GetLogManager()->DebugLog(_T("ERROR parsing block:\n") + buffer);
}
else
{
if (s_DebugSmartSense)
{
#if wxCHECK_VERSION(2, 9, 0)
Manager::Get()->GetLogManager()->DebugLog(F(_T("Block:\n%s"), buffer.wx_str()));
#else
Manager::Get()->GetLogManager()->DebugLog(F(_T("Block:\n%s"), buffer.c_str()));
#endif
Manager::Get()->GetLogManager()->DebugLog(_T("Local tokens:"));
for (size_t i = 0; i < parser->GetTokens()->size(); ++i)
{
Token* t = parser->GetTokens()->at(i);
if (t && t->m_IsTemp)
Manager::Get()->GetLogManager()->DebugLog(_T(" + ") + t->DisplayName());
}
}
return true;
}
}
else
{
if (s_DebugSmartSense)
Manager::Get()->GetLogManager()->DebugLog(_T("Could not determine current block start..."));
}
return false;
}
int variableA;
variableA = 1;
// always add scope -1 (i.e. global namespace)
search_scope->insert(-1);
// find all other matches
std::queue<ParserComponent> components;
BreakUpComponents(parser, actual, components);
m_LastAISearchWasGlobal = components.size() <= 1;
if (!components.empty())
m_LastAIGlobalSearch = components.front().component;
// actually find all matches in selected namespaces
for (TokenIdxSet::iterator it = search_scope->begin(); it != search_scope->end(); ++it)
{
if (s_DebugSmartSense)
{
Token* scopeToken = tree->at(*it);
#if wxCHECK_VERSION(2, 9, 0)
Manager::Get()->GetLogManager()->DebugLog(F(_T("Parent scope: '%s' (%d)"), scopeToken ? scopeToken->m_Name.wx_str() : _T("Global namespace"), *it));
#else
Manager::Get()->GetLogManager()->DebugLog(F(_T("Parent scope: '%s' (%d)"), scopeToken ? scopeToken->m_Name.c_str() : _T("Global namespace"), *it));
#endif
}
FindAIMatches(parser, components, result, *it, noPartialMatch, caseSensitive, true, 0xffff, search_scope);
}
cached_editor = editor;
if (result.size() || (m_EditorEndWord - m_EditorStartWord))
cached_editor_start_word = m_EditorStartWord;
cached_search = actual;
cached_results_count = result.size();
return result.size();
}
Hm, Olly having both in the tooltip can be quite helpful.Definitely. Look: Naming a local variable like a global one is bad style. Surely you might forget this sometimes but if the tooltip reminds you accordingly this is just helpful. So please don't strip this (really useful) information. Not even for the sake of speed.
Index: codecompletion.cpp
===================================================================
--- codecompletion.cpp (revision 5908)
+++ codecompletion.cpp (working copy)
@@ -112,25 +112,26 @@
// just because we don't know other plugins' used identifiers,
// we use wxNewId() to generate a guaranteed unique ID ;), instead of enum
// (don't forget that, especially in a plugin)
-int idMenuCodeComplete = wxNewId();
-int idMenuShowCallTip = wxNewId();
-int idMenuGotoFunction = wxNewId();
-int idMenuGotoPrevFunction = wxNewId();
-int idMenuGotoNextFunction = wxNewId();
-int idMenuGotoDeclaration = wxNewId();
-int idMenuGotoImplementation = wxNewId();
-int idMenuOpenIncludeFile = wxNewId();
-int idViewClassBrowser = wxNewId();
-int idEditorSubMenu = wxNewId();
-int idClassMethod = wxNewId();
+int idMenuCodeComplete = wxNewId();
+int idMenuShowCallTip = wxNewId();
+int idMenuGotoFunction = wxNewId();
+int idMenuGotoPrevFunction = wxNewId();
+int idMenuGotoNextFunction = wxNewId();
+int idMenuGotoDeclaration = wxNewId();
+int idMenuGotoImplementation = wxNewId();
+int idMenuOpenIncludeFile = wxNewId();
+int idViewClassBrowser = wxNewId();
+int idEditorSubMenu = wxNewId();
+int idClassMethod = wxNewId();
int idUnimplementedClassMethods = wxNewId();
-int idGotoDeclaration = wxNewId();
-int idGotoImplementation = wxNewId();
-int idOpenIncludeFile = wxNewId();
-int idStartParsingProjects = wxNewId();
-int idCodeCompleteTimer = wxNewId();
-int idFunctionsParsingTimer = wxNewId();
+int idGotoDeclaration = wxNewId();
+int idGotoImplementation = wxNewId();
+int idOpenIncludeFile = wxNewId();
+int idStartParsingProjects = wxNewId();
+int idCodeCompleteTimer = wxNewId();
+int idFunctionsParsingTimer = wxNewId();
+
// milliseconds
#define EDITOR_AND_LINE_INTERVAL 150
@@ -193,8 +194,14 @@
if (!cfg->Exists(_T("token_replacements")))
{
- // first run; add default replacements
+ // first run; add default replacements string
Tokenizer::SetReplacementString(_T("_GLIBCXX_STD"), _T("std"));
+ Tokenizer::SetReplacementString(_T("_GLIBCXX_BEGIN_NESTED_NAMESPACE"), _T("+namespace"));
+ Tokenizer::SetReplacementString(_T("_GLIBCXX_END_NESTED_NAMESPACE"), _T("}"));
+ Tokenizer::SetReplacementString(_T("_GLIBCXX_BEGIN_NAMESPACE"), _T("+namespace"));
+ Tokenizer::SetReplacementString(_T("_GLIBCXX_END_NAMESPACE_TR1"), _T("}"));
+ Tokenizer::SetReplacementString(_T("_GLIBCXX_BEGIN_NAMESPACE_TR1"), _T("-namespace tr1 {"));
+
}
else
cfg->Read(_T("token_replacements"), &repl);
@@ -522,9 +529,10 @@
if (!IsAttached() || !m_InitDone)
return -1;
- ConfigManager* cfg = Manager::Get()->GetConfigManager(_T("code_completion"));
+ ConfigManager* cfg = Manager::Get()->GetConfigManager(_T("code_completion"));
EditorManager* edMan = Manager::Get()->GetEditorManager();
- cbEditor* ed = edMan->GetBuiltinActiveEditor();
+ cbEditor* ed = edMan->GetBuiltinActiveEditor();
+
if (!ed)
return -3;
@@ -554,7 +562,8 @@
ed->GetControl()->ClearRegisteredImages();
bool caseSens = parser ? parser->Options().caseSensitive : false;
- wxArrayString items; items.Alloc(result.size());
+ wxArrayString items;
+ items.Alloc(result.size());
int pos = ed->GetControl()->GetCurrentPos();
int start = ed->GetControl()->WordStartPosition(pos, true);
wxArrayInt already_registered;
@@ -748,6 +757,8 @@
return dirs;
}
+// Do the code completion when we enter:
+// #include "| or #include <|
void CodeCompletion::CodeCompleteIncludes()
{
if (!IsAttached() || !m_InitDone)
@@ -758,20 +769,22 @@
return;
EditorManager* edMan = Manager::Get()->GetEditorManager();
- cbEditor* ed = edMan->GetBuiltinActiveEditor();
+ cbEditor* ed = edMan->GetBuiltinActiveEditor();
+
if (!ed)
return;
- Parser* parser = m_NativeParser.FindParserFromActiveEditor();
+ Parser* parser = m_NativeParser.FindParserFromActiveEditor();
const bool caseSens = parser ? parser->Options().caseSensitive : false;
FileType ft = FileTypeOf(ed->GetShortName());
if ( ft != ftHeader && ft != ftSource) // only parse source/header files
return;
- int pos = ed->GetControl()->GetCurrentPos();
+ int pos = ed->GetControl()->GetCurrentPos();
int lineStartPos = ed->GetControl()->PositionFromLine(ed->GetControl()->GetCurrentLine());
- wxString line = ed->GetControl()->GetLine(ed->GetControl()->GetCurrentLine());
+ wxString line = ed->GetControl()->GetLine(ed->GetControl()->GetCurrentLine());
+
//Manager::Get()->GetLogManager()->DebugLog("#include cc for \"%s\"", line.c_str());
line.Trim();
if (line.IsEmpty() || !TestIncludeLine(line))
@@ -784,6 +797,7 @@
return;
++quote_pos;
+ // now, we are after the quote prompt
wxString filename = line.substr(quote_pos, pos - lineStartPos - quote_pos);
filename.Replace(_T("\\"), _T("/"), true);
@@ -823,6 +837,7 @@
}
}
+ // popup the auto completion window
if (files.GetCount() != 0)
{
files.Sort();
@@ -872,11 +887,12 @@
// else, out of range
}
- int start = 0;
- int end = 0;
- int count = 0;
- int commas = m_NativeParser.GetCallTipCommas(); // how many commas has the user typed so far?
+ int start = 0;
+ int end = 0;
+ int count = 0;
+ int commas = m_NativeParser.GetCallTipCommas(); // how many commas has the user typed so far?
wxArrayString items = m_NativeParser.GetCallTips(maxCalltipLineSizeInChars);
+
std::set< wxString, std::less<wxString> > unique_tips; // check against this before inserting a new tip in the list
wxString definition;
for (unsigned int i = 0; i < items.GetCount(); ++i)
@@ -923,8 +939,11 @@
}
wxString filename = ed->GetFilename();
+
+ // open the insert class dialog
InsertClassMethodDlg dlg(Manager::Get()->GetAppWindow(), parser, filename);
PlaceWindow(&dlg);
+
if (dlg.ShowModal() == wxID_OK)
{
int pos = ed->GetControl()->GetCurrentPos();
@@ -1565,6 +1584,30 @@
if (!Manager::Get()->GetConfigManager(_T("code_completion"))->ReadBool(_T("eval_tooltip"), true))
return;
+
+ // Check the debugger is running...at this time, don't show cc tips
+ bool debuggerRunning = false;
+ PluginsArray arr = Manager::Get()->GetPluginManager()->GetOffersFor(ptDebugger);
+ if (arr.GetCount())
+ {
+ for(size_t i=0;i<arr.GetCount();i++)
+ {
+ cbDebuggerPlugin* debugger = (cbDebuggerPlugin*)arr[i];
+ if (!debugger)
+ continue; //kinda scary if this isn't a debugger? perhaps this should be a logged error??
+ if (debugger->IsRunning())
+ {
+ debuggerRunning=true;
+ break;
+ }
+ }
+ }
+ if(debuggerRunning)
+ {
+ Manager::Get()->GetLogManager()->DebugLog(F(_T("debugger is running, skip.CC tips..")));
+ return;
+ }
+
EditorBase* base = event.GetEditor();
cbEditor* ed = base && base->IsBuiltinEditor() ? static_cast<cbEditor*>(base) : 0;
if (!ed || ed->IsContextMenuOpened())
Index: classbrowserbuilderthread.cpp
===================================================================
--- classbrowserbuilderthread.cpp (revision 5908)
+++ classbrowserbuilderthread.cpp (working copy)
@@ -780,22 +780,29 @@
#ifdef buildtree_measuring
wxStopWatch sw;
#endif
+
tree->Freeze();
+
+
#ifdef buildtree_measuring
Manager::Get()->GetLogManager()->DebugLog(F(_T("tree->Freeze() took : %d ms"),sw.Time()));
sw.Start();
#endif
+
tree->DeleteAllItems();
#ifdef buildtree_measuring
Manager::Get()->GetLogManager()->DebugLog(F(_T("tree->DeleteAllItems() took : %d ms"),sw.Time()));
sw.Start();
#endif
+
node = tree->AddRoot(_T("Members")); // not visible, so don't translate
+
#ifdef buildtree_measuring
Manager::Get()->GetLogManager()->DebugLog(F(_T("tree->AddRoot() took : %d ms"),sw.Time()));
#endif
}
+ wxTreeItemId firtItem;
if (data)
{
switch (data->m_SpecialFolder)
@@ -819,6 +826,8 @@
AddChildrenOf(tree, rootFuncs, data->m_pToken->GetSelf(), tkFunction);
AddChildrenOf(tree, rootVars, data->m_pToken->GetSelf(), tkVariable);
AddChildrenOf(tree, rootOthers, data->m_pToken->GetSelf(), ~(tkNamespace | tkClass | tkEnum | tkAnyFunction | tkVariable));
+ firtItem = rootCtorDtor;
+
}
else if (m_Options.sortType == bstScope && data->m_pToken->m_TokenKind & tkClass)
{
@@ -829,6 +838,9 @@
AddChildrenOf(tree, rootPublic, data->m_pToken->GetSelf(), ~(tkNamespace | tkClass | tkEnum), tsPublic);
AddChildrenOf(tree, rootProtected, data->m_pToken->GetSelf(), ~(tkNamespace | tkClass | tkEnum), tsProtected);
AddChildrenOf(tree, rootPrivate, data->m_pToken->GetSelf(), ~(tkNamespace | tkClass | tkEnum), tsPrivate);
+
+ firtItem = rootPublic;
+
}
else
{
@@ -866,7 +878,19 @@
if (bottom)
{
tree->ExpandAll();
+//// if(tree->GetRootItem())
+// tree->EnsureVisible(tree->GetRootItem());
+ //tree->EnsureVisible(node);
+ if(firtItem.IsOk())
+ {
+ tree->ScrollTo(firtItem);
+ tree->EnsureVisible(firtItem);
+ }
tree->Thaw();
+ //we should scrool to the first item!!
+// wxTreeItemIdValue cookie;
+// wxTreeItemId res = tree->GetFirstChild(start, cookie);
+
}
}
void NativeParser::OnEditorActivated(EditorBase* editor)
{
if (!m_pClassBrowser)
return;
cbEditor* ed = editor && editor->IsBuiltinEditor() ? static_cast<cbEditor*>(editor) : 0;
// cbEditor* ed = editor ? static_cast<cbEditor*>(editor) : 0;
// EditorManager* edMan = Manager::Get()->GetEditorManager();
// cbEditor* ed = edMan->GetBuiltinActiveEditor();
if (ed)
{
Parser* parser = FindParserFromEditor(ed);
if (parser && parser->ClassBrowserOptions().displayFilter == bdfFile)
{
// check header and implementation file swap, if yes, don't need to rebuild browser tree
m_pClassBrowser->UpdateView(true); ***************here
}
}
}
Hi, all, here, I announce this patch of the code completion plugin.I am not sure about this one...
hi, all, here is another patch.
This is the third patch. I just add one major check,
I'm trying to document the parserthread.h.Those three are looking good to me. I've applied them in my local copy for testing... (where appropriate).
CVAPI(void) cvFunction(XXXXX);
I'm not satisfied with this, maybe, I need to implement a macro replacement rule for the "CVAPI" macro. Wink
we can make a compare here.I'd rather go with the token replacement as suggested by OllyDgb. This is configurable and we don't need to implement particular CV SDK hocus-pocus in the plugin. Thus the plugin should not know antyhing about CV. OR make it more generic so that it applies to other similar constructs as well. But this might break something else.
(1) There is a problem with typedefs with multiple definitions. For instance, typedef WNDCLASSEXW WNDCLASSEX,*LPWNDCLASSEX,*PWNDCLASSEX; wont get recognized by code complete, however, typedef WNDCLASSEXW WNDCLASSEX; will work.
_GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
/**
* @brief A standard container made up of unique keys, which can be
* retrieved in logarithmic time.
*
* @ingroup associative_containers
*
* Meets the requirements of a <a href="tables.html#65">container</a>, a
* <a href="tables.html#66">reversible container</a>, and an
* <a href="tables.html#69">associative container</a> (using unique keys).
*
* Sets support bidirectional iterators.
*
* @param Key Type of key objects.
* @param Compare Comparison function object type, defaults to less<Key>.
* @param Alloc Allocator type, defaults to allocator<Key>.
*
* The private tree data is declared exactly the same way for set and
* multiset; the distinction is made entirely in how the tree functions are
* called (*_unique versus *_equal, same as the standard).
*/
template<typename _Key, typename _Compare = std::less<_Key>,
typename _Alloc = std::allocator<_Key> >
class set
{
// concept requirements
typedef typename _Alloc::value_type _Alloc_value_type;
__glibcxx_class_requires(_Key, _SGIAssignableConcept)
__glibcxx_class_requires4(_Compare, bool, _Key, _Key,
_BinaryFunctionConcept)
__glibcxx_class_requires2(_Key, _Alloc_value_type, _SameTypeConcept)
public:
// typedefs:
//@{
/// Public typedefs.
typedef _Key key_type;
typedef _Key value_type;
typedef _Compare key_compare;
typedef _Compare value_compare;
typedef _Alloc allocator_type;
//@}
private:
typedef typename _Alloc::template rebind<_Key>::other _Key_alloc_type;
typedef _Rb_tree<key_type, value_type, _Identity<value_type>,
key_compare, _Key_alloc_type> _Rep_type;
_Rep_type _M_t; // Red-black tree representing set.
public:
//@{
/// Iterator-related typedefs.
typedef typename _Key_alloc_type::pointer pointer;
typedef typename _Key_alloc_type::const_pointer const_pointer;
typedef typename _Key_alloc_type::reference reference;
typedef typename _Key_alloc_type::const_reference const_reference;
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// DR 103. set::iterator is required to be modifiable,
// but this allows modification of keys.
typedef typename _Rep_type::const_iterator iterator;
typedef typename _Rep_type::const_iterator const_iterator;
typedef typename _Rep_type::const_reverse_iterator reverse_iterator;
typedef typename _Rep_type::const_reverse_iterator const_reverse_iterator;
typedef typename _Rep_type::size_type size_type;
typedef typename _Rep_type::difference_type difference_type;
//@}
// allocation/deallocation
/**
* @brief Default constructor creates no elements.
*/
set()
: _M_t() { }
/**
* @brief Creates a %set with no elements.
* @param comp Comparator to use.
* @param a An allocator object.
*/
explicit
set(const _Compare& __comp,
const allocator_type& __a = allocator_type())
: _M_t(__comp, __a) { }
......
......
if (token == _T("template"))
{
wxString args = m_Tokenizer.GetToken(false,true);
token = m_Tokenizer.GetToken();
if (args == _T("<>"))
{
m_Str.Clear();
wxString name = m_Tokenizer.GetToken();
args = m_Tokenizer.PeekToken(false,true);
m_Tokenizer.UngetToken();
}
if (token==ParserConsts::kw_class)
{
m_Str.Clear();
if (m_Options.handleClasses)
HandleClass(ctClass,args);
else
SkipToOneOfChars(ParserConsts::semicolonclbrace, true);
continue;
}
else if (token==ParserConsts::kw_struct)
{
m_Str.Clear();
if (m_Options.handleClasses)
HandleClass(ctStructure,args);
else
SkipToOneOfChars(ParserConsts::semicolonclbrace, true);
continue;
}
else
{
m_Tokenizer.UngetToken();
}
}
wxString GetToken(bool bGetValue = false, bool bTemplate = false);
wxString PeekToken(bool bGetValue = false, bool bTemplate = false);
I still can't understand what does these prototype means:Agreed, the interface could be more clear. Please PM visualfc so he can have a look into...Code:(wxString GetToken(bool bGetValue = false, bool bTemplate = false);
wxString PeekToken(bool bGetValue = false, bool bTemplate = false);
Thanks, that's great that we have the same consideration :D.I still can't understand what does these prototype means:Agreed, the interface could be more clear. Please PM visualfc so he can have a look into...Code:(wxString GetToken(bool bGetValue = false, bool bTemplate = false);
wxString PeekToken(bool bGetValue = false, bool bTemplate = false);
Currently, a workaround is to remove the "handling template related code". :DTrue, but in fact I added this to trunk because in fact it helps a lot if it works. In my own projects I use templates on a "normal" level and it works very well there and thus is really helpful (for me at least).
else if (CurrentChar() == '<' && bTemplate)
{
MoveToNextChar();
if (!SkipToOneOfChars(_T(">\r\n")), false)
return wxEmptyString;
MoveToNextChar();
wxString tmp = m_Buffer.Mid(start+1,m_TokenIndex-start-2);
tmp.Trim();
str = _T("<");
str += tmp;
str += _T(">"); // m_Buffer.Mid(start, m_TokenIndex - start);
}
So, what does the SkipToOneOfChars(_T(">\r\n")), false) means?So it seems VisualFC assumed that template arguments are no longer than a single line which isn't true for the STL set as you've seen... :lol:
UnWanted
Preprocessor
Template
void ParserThread::HandleXXXXXX()
{
// need to force the tokenizer _not_ skip anything
// or else default values for template params would cause us to miss everything (because of the '=' symbol)
bool oldState = m_Tokenizer.IsSkippingUnwantedTokens();
m_Tokenizer.SetSkipUnwantedTokens(false);
DoSomething();
m_Tokenizer.SetSkipUnwantedTokens(oldState);
}
void ParserThread::HandleXXXXXX()
{
m_Tokenizer.PushState();
m_Tokenizer.SetState(YYYYY);
DoSomething();
m_Tokenizer.PopState();
}
So, what does the SkipToOneOfChars(_T(">\r\n")), false) means?So it seems VisualFC assumed that template arguments are no longer than a single line which isn't true for the STL set as you've seen... :lol:
if ( !SkipToOneOfChars(_T(">\r\n")), false )
if ( XXXX, false)
Patch to fix the "template reading bug" ,Wow, that was fast (I didn't even manage to run C::B today). IF this works that would be nice!
void f(XXX);
void
f
(XXX)
;
struct Token{
wxString name;
Tokentype type;
}
void its type is normalText
f its type is normalText
(XXX) its type is functionArgument
; its type is endofStatement
else if (CurrentChar() == '<' && bTemplate)
{
MoveToNextChar();
if (!SkipToOneOfChars(_T(">")), true)
return wxEmptyString;
MoveToNextChar();
wxString tmp = m_Buffer.Mid(start+1,m_TokenIndex-start-2);
tmp.Trim();
str = _T("<");
str += tmp;
str += _T(">"); // m_Buffer.Mid(start, m_TokenIndex - start);
type = TemplateArgument;
}
else if (c == '(')
{
m_IsOperator = false;
// skip blocks () []
if (!SkipBlock(CurrentChar()))
return wxEmptyString;
str = FixArgument(m_Buffer.Mid(start, m_TokenIndex - start));
CompactSpaces(str);
type = functionArgument;
}
else
{
if (c == '{')
++m_NestLevel;
type = OpenBrace
else if (c == '}')
--m_NestLevel;
type = CloseBrace
str = c;
MoveToNextChar();
}
enum Tokentype{
normalText;
OpenBrace;
CloseBrace;
EndOfStatement;
FunctionArgument;
TemplateArgument;
....
}
switch(type){
case normaltext: XXXX
case:functionArgument: XXXX
}
Patch to fix the "template reading bug" , this patch contains some patch in CC comments improvement
#define PARSERTHREAD_DEBUG_OUTPUT 0
Index: src/plugins/codecompletion/parser/parserthread.cpp
===================================================================
--- src/plugins/codecompletion/parser/parserthread.cpp (revision 5986)
+++ src/plugins/codecompletion/parser/parserthread.cpp (working copy)
@@ -661,17 +661,17 @@
&& (!m_pLastParent || m_pLastParent->m_Name != token) ) // if func has same name as current scope (class)
{
// test Macro
- if (token.Upper() == token)
+ /*if (token.Upper() == token)
{
HandleMacro(token, peek);
m_Tokenizer.GetToken();
m_Str.Clear();
}
else
- {
+ {*/
wxString arg = m_Tokenizer.GetToken(); // eat args ()
m_Str = token+arg;
- }
+ //}
}
else if (peek.GetChar(0) == '(' && m_Options.handleFunctions)
{
can you comment these codes,because they make no sense.Why exactly does that make no sense? Because if commented macros are not being handeled at all.
if (token.Upper() == token)
LINUX(ARG) ---------------work.This is true, however, macros are usually uppercase it's like a rule everybody should follow. In addition it worked nicely for me for quite some macros that were CC'ed very nicely afterwards. However, I agree that the detection algorithm should be more precise. So I'll comment it for a while and add a ToDo there...
linUX(ARG) ----------------not work
1. Could this function be called only when "Display inheritance info" is selected in the options page or "Show inherited members" is selected from the right-click menu?To make it simple: 1.) Yes, 2.) Yes, 3.) Yes.
2. Could this thing be performed in the parser thread?
3. Could this function be done in a smarter way?
Your opinion?
class AClass
{
AClass(int a, int b)
{
}
int method(int b) { return 0; }
};
int main()
{
AClass a(5, 6);
a.method(1);
return 0;
}
Simple example that breaks the completion. Place the code below in the main.cpp of new console project:Code
class AClass
{
AClass(int a, int b)
{
}
int method(int b) { return 0; }
};
int main()
{
AClass a(5, 6);
a.method(1);
return 0;
}
Steps
0. Save the file
1. Place the currsor at the end of line "a.method(1);"
2. Press enter
3. Type "a."
4. Press ctrl+space
5. Nothing shows
Also the calltip for the constructor call doesn't work :(
Using latest version from trunk (6023).
Works fine here (debian 64-bit).Both work (the completion and the calltip problems)?
Works fine here (debian 64-bit).Both work (the completion and the calltip problems)?
struct TestStruct
{
int a;
int Test()
{
int test_1, test_2;
tes
}
};
Another bug, this time 100% reproducible:
struct TestStruct
{
int test_3;
int Test()
{
int test_1, test_2;
te
}
};
template
Test
test_3
struct TestStruct
{
int test_3;
int Test()
{
int test_1, test_2;
test_
}
};
struct TestStruct
{
int aaaaa;
int Test()
{
int test_1, test_2;
test_
}
};
// Start an Artificial Intelligence (!) sequence to gather all the matching tokens..
// The actual AI is in FindAIMatches() below...
size_t NativeParser::AI(TokenIdxSet& result,
cbEditor* editor,
const wxString& lineText,
bool noPartialMatch,
bool caseSensitive,
TokenIdxSet* search_scope,
int caretPos)
{
......
......
if (result.size()<1) // found nothing in the search_scope, add global namespace
{
if (s_DebugSmartSense)
Manager::Get()->GetLogManager()->DebugLog(F(_T("AI() result is zero. Adding global namespace.")));
search_scope->insert(-1);
FindAIMatches(components, result, -1, noPartialMatch, caseSensitive, true, 0xffff, search_scope);
}
......
struct TestStruct
{
int test_3;
int Test()
{
int test_1, test_2;
te
}
};
{
int test_1, test_2;
te
}
int abcd;
int main()
{
int abcd;
ab
}
struct TestStruct
{
int test_3;
int Test()
{
int test_1, test_2;
te
}
};
We firstly add the initial scope is "struct TestStruct", then do the AIMatch routing in this scope. Too bad that when the "local parser" parsing the local statement, both "test_1" and "test_2" will added to the "global scope namespace":Code{
int test_1, test_2;
te
}
So, when we do a AIMatch in the "strct TestStruct", we find we get the two matches: "Test()" and the member variable "test_3". At this time, we have already get the matching result size >1, so, due to the if condition, global namespace is not searched any more.
#define CONDITION
#if defined(SOMETHING)
#include "something.h"
#elif defined(CONDITION)
#include "class1.h"
#endif
int main()
{
return 0;
}
It is not a bug.it can be fixed easily. :D@oBFusCATed
OK, Might test it...In fact, only one statement do the hack:
search_scope->insert(-1);//alwayser search the global scope.