I've wrote a basic implementation, but it only does substring tests, so it's not suited for a full match or duplicates. I guess it'll require regex support to handle those.
Notes:
1) I've also fixed some trimming while I was at it. (wxString::Trim(bool trim_right) defaults to true and cctest did two Trim().. one with default true and one with implicit true)
2) the code inside the constructor isn't required since it's usually the default anyway... but maybe do it implicit nontheless
3) the patch to src/plugins/codecompletion/parser/parser_base.cpp should be properly redone, or at least every use of it verified since it'll probably always default to storeDocumentation = true even in situations where it "shouldn't"
4) the last "test" should fail... there are 2 special test values for doxygen comments, "*" as a "non-empty" wildcard, and "-" to check for empty docs
.../codecompletion/cctest/nativeparser_test.cpp | 86 +++++++++++++++++-----
1 file changed, 67 insertions(+), 19 deletions(-)
diff --git a/src/plugins/codecompletion/cctest/nativeparser_test.cpp b/src/plugins/codecompletion/cctest/nativeparser_test.cppindex 44c3059..b659657 100644--- a/src/plugins/codecompletion/cctest/nativeparser_test.cpp+++ b/src/plugins/codecompletion/cctest/nativeparser_test.cpp@@ -66,6 +66,8 @@ namespace CCTestAppGlobal
NativeParserTest::NativeParserTest()
{
+ m_Parser.Options().wantPreprocessor = true; // Default+ m_Parser.Options().storeDocumentation = true; // Default
}
NativeParserTest::~NativeParserTest()
@@ -235,29 +237,46 @@ bool NativeParserTest::ParseAndCodeCompletion(wxString filename, bool isLocalFil
// do tests here, example of line is below
// tc.St //StaticVoid
// remove the beginning "//"
- str.Remove(0,2);+ str.Remove(0, 2);+ + int pos;+ wxString expression;+ wxString match;+ wxString match_doc;+ + // find the optional "///<" for Doxygen comment tests+ pos = str.Find(_T("///<"));+ if (pos != wxNOT_FOUND)+ {+ match_doc = str.Mid(pos + 4);+ str = str.Mid(0, pos);+ }
// find the second "//", the string after the second double slash are the
// the result should be listed
- wxString expression;- wxString match;- int pos = str.Find(_T("//"));- if (pos == wxNOT_FOUND)- break;- expression = str.Mid(0,pos);- match = str.Mid(pos+2);// the remaining string+ pos = str.Find(_T("//"));+ if (pos != wxNOT_FOUND)+ {+ expression = str.Mid(0, pos);+ match = str.Mid(pos + 2);// the remaining string+ }+ else+ {+ expression = str;+ if (!match_doc.IsEmpty())+ match = _T("* @doxygen");+ }- expression.Trim();- expression.Trim(true);- match.Trim();- match.Trim(true);+ expression.Trim(true).Trim(false);+ match.Trim(true).Trim(false);+ match_doc.Trim(true).Trim(false);
wxArrayString suggestList;
// the match can have many items, like: AAA,BBBB
wxStringTokenizer tkz(match, wxT(","));
while ( tkz.HasMoreTokens() )
{
- wxString token = tkz.GetNextToken();+ wxString token = tkz.GetNextToken().Trim(true).Trim(false);
suggestList.Add(token);
}
@@ -279,13 +298,42 @@ bool NativeParserTest::ParseAndCodeCompletion(wxString filename, bool isLocalFil
if (!token || token->m_Name.IsEmpty())
continue;
- if (element.IsSameAs(token->m_Name))+ if (element.IsSameAs(token->m_Name) || element[0] == '*')
{
- message = wxString::Format(_T("+ PASS: %s %s"), expression.wx_str(), element.wx_str());- testResult << message << wxT("\n");- wxLogMessage(message);- pass = true;- passCount++;+ if (match_doc.IsEmpty())+ {+ message = wxString::Format(_T("+ PASS: %s %s"), expression.wx_str(), element.wx_str());+ testResult << message << wxT("\n");+ wxLogMessage(message);+ pass = true;+ ++passCount;+ }+ else+ {+ if (token->m_Doc.Contains(match_doc)+ || (match_doc[0] == '*' && match_doc.Len() == 1 && !token->m_Doc.IsEmpty())+ || (match_doc[0] == '-' && match_doc.Len() == 1 && token->m_Doc.IsEmpty()))+ {+ message = wxString::Format(_T("+ PASS: %s %s \"%s\""), expression.wx_str(), token->m_Name.wx_str(), match_doc.wx_str());+ testResult << message << wxT("\n");+ wxLogMessage(message);+ if (!pass)+ {+ pass = true;+ ++passCount;+ }+ }+ else+ {+ if (pass)+ --passCount;+ pass = false;+ element = wxString::Format(_T("%s \"%s\""), token->m_Name.wx_str(), match_doc.wx_str());+ break;+ }+ }+ if (element[0] != '*')+ break;
}
}
ParserThread::ParserThread(ParserBase*parent,constwxString& bufferOrFilename,boolisLocal,ParserThreadOptions& parserThreadOptions,TokenTree*tokenTree):m_Tokenizer(tokenTree),m_Parent(parent),m_TokenTree(tokenTree),m_LastParent(0),m_LastScope(tsUndefined),m_FileSize(0),m_FileIdx(0),m_IsLocal(isLocal),m_Options(parserThreadOptions),m_ParsingTypedef(false),m_Buffer(bufferOrFilename),m_StructUnionUnnamedCount(0),m_EnumUnnamedCount(0){m_Tokenizer.SetTokenizerOption(parserThreadOptions.wantPreprocessor,parserThreadOptions.storeDocumentation);if(!m_TokenTree)cbThrow(_T("m_TokenTree is a nullptr?!"));}
From af1b96e8ec639907f54e137d721677289f4542a3 Mon Sep 17 00:00:00 2001
From: asmwarrior <asmwarrior@gmail.com>
Date: Wed, 7 Sep 2016 21:59:38 +0800
Subject: patch3: two changes here: 1: enable the store doxygen option 2: first
mark the file in the TokenTree, so that the doxygen document is stored in the
Token::m_Doc, otherwise, it was wrongly stored in the m_ImpDoc. See Token*
ParserThread::DoAddToken() about how the doxygen document are added to the
Token.
diff --git a/src/plugins/codecompletion/parser/parser_base.cpp b/src/plugins/codecompletion/parser/parser_base.cpp
index 82e1a55..4a4641d 100644
--- a/src/plugins/codecompletion/parser/parser_base.cpp
+++ b/src/plugins/codecompletion/parser/parser_base.cpp
@@ -229,8 +229,15 @@ bool ParserBase::Reparse(const wxString& file, cb_unused bool isLocal)
opts.handleEnums = true; // default
opts.handleTypedefs = true; // default
+ opts.storeDocumentation = true; // enable this option to enable cctest for doxygen doc reading
+
opts.loader = loader;
+ // the file should first put in the TokenTree, so the index is correct when initlize the
+ // Tokenizer object inside the ParserThread::ParserThread()
+
+ m_TokenTree->ReserveFileForParsing(file, true);
+
ParserThread* pt = new ParserThread(this, file, true, opts, m_TokenTree);
bool success = pt->Parse();
delete pt;
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
oh right... my patch to src/plugins/codecompletion/parser/parser_base.cpp only covered the case where manual input in cctest is used...
Though, can't we just do it the way Code::Blocks does? (I guess it never uses ParseBuffer() but it should use files^^)
Or what's the difference and why?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
oh right... my patch to src/plugins/codecompletion/parser/parser_base.cpp only covered the case where manual input in cctest is used...Though, can't we just do it the way Code::Blocks does? (I guess it never uses ParseBuffer() but it should use files^^)
Or what's the difference and why?
The function call "m_TokenTree->ReserveFileForParsing(file, true);" follows the way the native codecompletion's parser does.
Each file in the TokenTree has an index, so we need to call ReserveFileForParsing() first to give a file index for the file. And later, both the Parserthread and the Tokenizer will use this file index.
For parsing the buffer, I'm not quite sure, maybe, an editor buffer does not have a file index, so it use the file index default 0.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
OK, I found a bug that the doxygen documents are not added to the Token, because macro definitions are added in the Tokenizer class(not in the parserthread class), so, here is a simple fix:
From 20e4325687084f3747fae52d2a0c1c2eede850ce Mon Sep 17 00:00:00 2001
From: asmwarrior <asmwarrior@gmail.com>
Date: Wed, 7 Sep 2016 22:35:02 +0800
Subject: * fix a bug that we have forget adding the doxygen documents for
macro definitions.
diff --git a/src/plugins/codecompletion/parser/tokenizer.cpp b/src/plugins/codecompletion/parser/tokenizer.cpp
index 467135a..16bdc1e 100644
--- a/src/plugins/codecompletion/parser/tokenizer.cpp
+++ b/src/plugins/codecompletion/parser/tokenizer.cpp
@@ -2029,4 +2029,7 @@ void Tokenizer::AddMacroDefinition(wxString name, int line, wxString para, wxStr
// update the definition
token->m_Args = para; // macro call's formal args
token->m_FullType = substitues; // replace list
+
+ // this will append the doxygen style comments to the Token
+ SetLastTokenIdx(token->m_Index);
}
I've wrote a basic implementation, but it only does substring tests, so it's not suited for a full match or duplicates. I guess it'll require regex support to handle those.
Notes:
1) I've also fixed some trimming while I was at it. (wxString::Trim(bool trim_right) defaults to
true
and cctest did two Trim().. one with defaulttrue
and one with implicittrue
)2) the code inside the constructor isn't required since it's usually the default anyway... but maybe do it implicit nontheless
3) the patch to
src/plugins/codecompletion/parser/parser_base.cpp
should be properly redone, or at least every use of it verified since it'll probably always default tostoreDocumentation = true
even in situations where it "shouldn't"4) the last "test" should fail... there are 2 special test values for doxygen comments, "*" as a "non-empty" wildcard, and "-" to check for empty docs
But it'll only work with this patch also applied:
And a test case (which currently fails all #define comments in my build...)
Thanks, save the test file as ccc_parse_doxygen_document.cpp, and run the tests, here is the result.
So, a "-" rule means the token don't have doxygen documents?
EDIT: Oh, you have already stated that:
Last edit: ollydbg 2016-09-07
It looks like token->m_Doc is always empty string, not sure why, let's look into the code.
EDIT:
it looks like m_TokenizerOptions.storeDocumentation is false when parsing the file.
Last edit: ollydbg 2016-09-07
OK, found the reason:
and
But the ParserThreadOptions has the field storeDocumentation = false
OK, now, I can see some tests are passed, see the result below:
With such changes
oh right... my patch to
src/plugins/codecompletion/parser/parser_base.cpp
only covered the case where manual input in cctest is used...Though, can't we just do it the way Code::Blocks does? (I guess it never uses
ParseBuffer()
but it should use files^^)Or what's the difference and why?
The function call "m_TokenTree->ReserveFileForParsing(file, true);" follows the way the native codecompletion's parser does.
Each file in the TokenTree has an index, so we need to call ReserveFileForParsing() first to give a file index for the file. And later, both the Parserthread and the Tokenizer will use this file index.
For parsing the buffer, I'm not quite sure, maybe, an editor buffer does not have a file index, so it use the file index default 0.
OK, I found a bug that the doxygen documents are not added to the Token, because macro definitions are added in the Tokenizer class(not in the parserthread class), so, here is a simple fix:
After this fix, I get such results:
This is the expect result. The 1 FAIL is also correct, because DEF1 did have doxygen documents.
Great job, White Tiger!
The modified patch is in trunk now(rev10902), Thanks!