From 0a88a2dcd051ad13951b42649cc58e6bd466f655 Mon Sep 17 00:00:00 2001 From: babaybus Date: Sun, 8 Aug 2010 00:00:00 +0000 Subject: [PATCH] Version 0.2.9 Correct bugs related to templates and add support for throw statement (many thanks to Dennis Lubert): - Template parameter of different type from class and typename are recognized. - Indentation mistake while detecting template. - New options are available: g:DoxygenToolkit_throwTag_pre (default set to '@throw ', can be changed to '@exception ' and g:DoxygenToolkit_throwTag_post --- plugin/DoxygenToolkit.vim | 113 +++++++++++++++++++++++++++++--------- 1 file changed, 86 insertions(+), 27 deletions(-) diff --git a/plugin/DoxygenToolkit.vim b/plugin/DoxygenToolkit.vim index 2fc1dc1..30e3a9d 100644 --- a/plugin/DoxygenToolkit.vim +++ b/plugin/DoxygenToolkit.vim @@ -1,13 +1,21 @@ " DoxygenToolkit.vim " Brief: Usefull tools for Doxygen (comment, author, license). -" Version: 0.2.8 -" Date: 08/06/09 +" Version: 0.2.9 +" Date: 2009/08/08 " Author: Mathias Lorente " " TODO: add automatically (option controlled) in/in out flags to function " parameters " TODO: (Python) Check default paramareters defined as list/dictionnary/tuple " +" Note: Correct bugs related to templates and add support for throw statement +" (many thanks to Dennis Lubert): +" - Template parameter of different type from class and typename are +" recognized. +" - Indentation mistake while detecting template. +" - New option are available: g:DoxygenToolkit_throwTag_pre and +" g:DoxygenToolkit_throwTag_post +" " Note: Add support for documentation of template parameters. " Thanks to Dennis (plasmahh) and its suggestions. " - New option are available: g:DoxygenToolkit_templateParamTag_pre @@ -232,8 +240,8 @@ " Verify if already loaded "if exists("loaded_DoxygenToolkit") -" echo 'DoxygenToolkit Already Loaded.' -" finish +" echo 'DoxygenToolkit Already Loaded.' +" finish "endif let loaded_DoxygenToolkit = 1 "echo 'Loading DoxygenToolkit...' @@ -272,6 +280,12 @@ endif if !exists("g:DoxygenToolkit_returnTag") let g:DoxygenToolkit_returnTag = "@return " endif +if !exists("g:DoxygenToolkit_throwTag_pre") + let g:DoxygenToolkit_throwTag_pre = "@throw " " @exception is also valid +endif +if !exists("g:DoxygenToolkit_throwTag_post") + let g:DoxygenToolkit_throwTag_post = "" +endif if !exists("g:DoxygenToolkit_blockHeader") let g:DoxygenToolkit_blockHeader = "" endif @@ -528,6 +542,7 @@ function! DoxygenCommentFunc() let l:endDocPattern = ';\|{\|\%([^:]\zs:\ze\%([^:]\|$\)\)' let l:commentPattern = '\%(/*\)\|\%(//\)\' let l:templateParameterPattern = "<[^<>]*>" + let l:throwPattern = '.*\[[:blank:]]*(\([^()]*\)).*' "available only for 'cpp' type let l:classPattern = '\[[:blank:]]\+\zs'.l:someNameWithNamespacePattern.'\ze.*\%('.l:endDocPattern.'\)' let l:structPattern = '\[[:blank:]]\+\zs'.l:someNameWithNamespacePattern.'\ze[^(),]*\%('.l:endDocPattern.'\)' @@ -550,7 +565,7 @@ function! DoxygenCommentFunc() let l:count = 1 let l:endDocFound = 0 - let l:doc = { "type": "", "name": "None", "params": [], "returns": "" , "templates": [] } + let l:doc = { "type": "", "name": "None", "params": [], "returns": "" , "templates": [], "throws": [] } " Mark current line for future use mark d @@ -577,13 +592,28 @@ function! DoxygenCommentFunc() " Look for the end of the function/class/... to document " TODO does not work when function/class/... is commented out! + let l:readError = "Cannot reach end of function/class/... declaration!" let l:count = 0 + let l:throwCompleted = 0 + let l:endReadPattern = l:endDocPattern while( l:endDocFound == 0 && l:count < g:DoxygenToolkit_maxFunctionProtoLines ) let l:lineBuffer = s:RemoveComments( l:lineBuffer ) " Valid only for cpp. For Python it must be 'class ...:' or 'def ...:' or " '... EOL'. - if( match( l:lineBuffer, l:endDocPattern ) != -1 ) - let l:endDocFound = 1 + if( match( l:lineBuffer, l:endReadPattern ) != -1 ) + " Look for throw statement at the end + if( s:CheckFileType() == "cpp" && l:throwCompleted == 0 ) + " throw statement can have already been read or can be on next line + if( match( l:lineBuffer.' '.getline( line ( "." ) + 1 ), '.*\.*' ) != -1 ) + let l:endReadPattern = l:throwPattern + let l:throwCompleted = 1 + let l:readError = "Cannot reach end of throw statement" + else + let l:endDocFound = 1 + endif + else + let l:endDocFound = 1 + endif continue endif exec "normal j" @@ -596,7 +626,7 @@ function! DoxygenCommentFunc() " Fall here when only comments have been found. call s:WarnMsg( "Nothing to document here!" ) else - call s:WarnMsg( "Cannot reach end of function/class/... declaration!" ) + call s:WarnMsg( l:readError ) endif exec "normal `d" return @@ -650,6 +680,9 @@ function! DoxygenCommentFunc() else let l:doc.type = 'function' call s:ParseFunctionParameters( l:lineBuffer, l:doc ) + if( l:throwCompleted == 1 ) + call s:ParseThrowParameters( l:lineBuffer, l:doc, l:throwPattern ) + endif endif " This is an attribute for Python @@ -708,7 +741,7 @@ function! DoxygenCommentFunc() let s:insertEmptyLine = 1 endif for param in l:doc.templates - if( s:insertEmptyLine == 1 ) + if( s:insertEmptyLine == 1 ) exec "normal o".s:interCommentTag let s:insertEmptyLine = 0 endif @@ -730,6 +763,22 @@ function! DoxygenCommentFunc() exec "normal o".s:interCommentTag.g:DoxygenToolkit_returnTag endif + " Exception (throw) values (cpp only) + if( len( l:doc.throws ) > 0 ) + if( g:DoxygenToolkit_compactDoc =~ "yes" ) + let s:insertEmptyLine = 0 + else + let s:insertEmptyLine = 1 + endif + for param in l:doc.throws + if( s:insertEmptyLine == 1 ) + exec "normal o".s:interCommentTag + let s:insertEmptyLine = 0 + endif + exec "normal o".s:interCommentTag.g:DoxygenToolkit_throwTag_pre.g:DoxygenToolkit_throwTag_post.param + endfor + endif + " End (if any) of documentation block. if( s:endCommentTag != "" ) if( s:compactOneLineDoc =~ "yes" ) @@ -845,7 +894,7 @@ function! s:ParseFunctionParameters( lineBuffer, doc ) " all the function definition to know whether a value is returned or not. if( s:CheckFileType() == "cpp" ) let l:functionBuffer = strpart( a:lineBuffer, 0, l:paramPosition ) - " Remove unnecessary elements + " Remove unnecessary elements for ignored in g:DoxygenToolkit_ignoreForReturn let l:functionBuffer = substitute( l:functionBuffer, '\<'.ignored.'\>', '', 'g' ) endfor @@ -860,7 +909,7 @@ function! s:ParseFunctionParameters( lineBuffer, doc ) let l:parametersBuffer = strpart( a:lineBuffer, l:paramPosition + 1 ) " Remove trailing closing bracket and everything that follows and trim. if( s:CheckFileType() == "cpp" ) - let l:parametersBuffer = substitute( l:parametersBuffer, ')[^)]*\%(;\|{\|\%([^:]:\%([^:]\|$\)\)\).*', '', '' ) + let l:parametersBuffer = substitute( l:parametersBuffer, ')[^)]*\%(;\|{\|\%([^:]:\%([^:]\|$\)\)\|\%(\\)\).*', '', '' ) else let l:parametersBuffer = substitute( l:parametersBuffer, ')[^)]*:.*', '', '' ) endif @@ -966,25 +1015,35 @@ endfunction " Extract template parameter name for function/class/method """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" function! s:ParseFunctionTemplateParameters( lineBuffer, doc ) - if( match( a:lineBuffer, '^template' ) == 0 ) - let l:firstIndex = stridx( a:lineBuffer, '<' ) - if( l:firstIndex != -1 ) - let l:lastIndex = stridx( a:lineBuffer, '>', l:firstIndex + 1 ) - if( l:lastIndex != -1 ) - " Keep only template parameters - let l:parameters = strpart( a:lineBuffer, l:firstIndex + 1, l:lastIndex - l:firstIndex - 1) - " Split on separator (,) - let l:params = split( l:parameters, '\,' ) - for param in l:params - " Extract template parameter name - let l:paramName = substitute(param, '[[:blank:]]*\%(\%(class\)\|\%(typename\)\)[[:blank:]]*\([^[:blank:]=]*\).*', '\1', '' ) - call add( a:doc.templates, l:paramName ) - endfor - endif - endif + if( match( a:lineBuffer, '^[[:blank:]]*template' ) == 0 ) + let l:firstIndex = stridx( a:lineBuffer, '<' ) + if( l:firstIndex != -1 ) + let l:lastIndex = stridx( a:lineBuffer, '>', l:firstIndex + 1 ) + if( l:lastIndex != -1 ) + " Keep only template parameters + let l:parameters = strpart( a:lineBuffer, l:firstIndex + 1, l:lastIndex - l:firstIndex - 1) + " Split on separator (,) + let l:params = split( l:parameters, '\,' ) + for param in l:params + " Extract template parameter name + let l:paramName = split( split( param, '=' )[0], '[[:blank:]]' )[-1] + call add( a:doc.templates, l:paramName ) + endfor + endif + endif endif endfunction +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +" Extract throw parameter name +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +function! s:ParseThrowParameters( lineBuffer, doc, throwPattern ) + let l:throwParams = substitute( a:lineBuffer, a:throwPattern, '\1', "" ) + for param in split( l:throwParams, "," ) + call add( a:doc.throws, substitute( param, '[[:blank:]]', '', "" ) ) + endfor +endfunction + """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" " Define start/end documentation format and backup generic parameters. """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""