Thread: [Doxygen-users] Whither Fortran type-bound procedure documentation?
Brought to you by:
dimitri
From: Hambley, M. <mat...@me...> - 2016-09-22 09:25:08
|
My original attempt to send this overtook my joining the mailing list so it is lost in limbo somewhere. Doxygen's approach to type-bound procedures in Fortran seems a little problematic. I've looked through my Doxyfile but can't see anything obvious which I should be changing but haven't. Let me elucidate: There are two places where one could put the documentation. Along with the declaration of the procedure, in the type definition. Alternatively it could go with the definition in the module body. Currently Doxygen seems to expect it to accompany declaration and ignores anything provided with definition. There are a number of issues with this. The calling signature of the procedure is not described in the declaration so Doxygen complains that you have @param clauses for non-existent arguments. Of course they do exist, just down in the definition. If you have a "generic" procedure, one which maps to a number of different implementations, i.e. overloaded, It can not be sensibly documented at declaration as there are multiple procedures but only one comment block. The upshot of all this is that the support for documentation seems to be in the wrong place. It would seem to make more sense for it to be with the procedure definition in the module body rather than in the module header in the type definition. Am I missing something? Is there already a way to get the behaviour I want? Or is this a shortcoming in the tool? -- Matthew Hambley Scientific Software Engineer Met Office Hadley Centre, Exeter, UK |
From: Albert <alb...@gm...> - 2016-09-22 09:57:03
|
Matthew, Can you create a small example to show the short comings? Best Regards, Albert On Thu, Sep 22, 2016 at 11:25 AM, Hambley, Matthew < mat...@me...> wrote: > My original attempt to send this overtook my joining the mailing list so > it is lost in limbo somewhere. > > Doxygen's approach to type-bound procedures in Fortran seems a little > problematic. I've looked through my Doxyfile but can't see anything obvious > which I should be changing but haven't. > > Let me elucidate: > > There are two places where one could put the documentation. Along with the > declaration of the procedure, in the type definition. Alternatively it > could go with the definition in the module body. > > Currently Doxygen seems to expect it to accompany declaration and ignores > anything provided with definition. > > There are a number of issues with this. > > The calling signature of the procedure is not described in the declaration > so Doxygen complains that you have @param clauses for non-existent > arguments. Of course they do exist, just down in the definition. > > If you have a "generic" procedure, one which maps to a number of different > implementations, i.e. overloaded, It can not be sensibly documented at > declaration as there are multiple procedures but only one comment block. > > The upshot of all this is that the support for documentation seems to be > in the wrong place. It would seem to make more sense for it to be with the > procedure definition in the module body rather than in the module header in > the type definition. > > Am I missing something? Is there already a way to get the behaviour I > want? Or is this a shortcoming in the tool? > > -- > Matthew Hambley > Scientific Software Engineer > Met Office Hadley Centre, Exeter, UK > > > > ------------------------------------------------------------ > ------------------ > _______________________________________________ > Doxygen-users mailing list > Dox...@li... > https://lists.sourceforge.net/lists/listinfo/doxygen-users > |
From: Hambley, M. <mat...@me...> - 2016-09-22 13:45:28
Attachments:
test_mod.f90
|
From: Albert [mailto:alb...@gm...] > > Can you create a small example to show the short comings? Of course. What follows is a Fortran module which should illustrate what I am trying to describe. (Object Fortran is, sadly, never short) Having carefully laid it out I suddenly had a nasty realisation that Outlook is probably about to mangle it horrible so I've attached a copy as well. Skip past the source code for commentary. module test_mod use iso_fortran_env, only : output_unit implicit none private !> @brief Type which does a thing !> @details Documented where we would expect. !> type, public :: test_type private integer, allocatable :: foo(:) contains private !> @brief Document in the type declaration !> @details Not so good as there are no arguments here. If they are !> documented here they show up in documentation but Doxygen !> complains about them being documented but not existing. Of !> course they do, but further down. !> !> Regardless the documentation is separate from the !> implementation. !> @param teapot Some argument. !> procedure, public :: wobble procedure, public :: wubble generic, public :: wibble => wibble_integer, wibble_real !> @brief One aspect of wibble !> @details I can document this here but it appears as a method of !> the type whereas really it should appear under !> "wibble". After all, it is private and not part of the !> API. !> procedure wibble_integer procedure wibble_real final :: destroy_test end type test_type interface test_type procedure create_test_default !> @brief Specific initialiser !> @details Will this how up? No it will not. procedure create_test_specific end interface test_type contains !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !> @brief Default initialiser !> !> @details It would be nice to document this here but it wont show up. !> function create_test_default() result(new_test) implicit none type(test_type) :: new_test allocate( new_test%foo(10) ) end function create_test_default !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! function create_test_specific( tally ) result(new_test) implicit none integer, intent(in) :: tally type(test_type) :: new_test allocate( new_test%foo(tally) ) end function create_test_specific !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !> @brief Destructor. !> @details Would prefer to document this here. !> subroutine destroy_test( this ) implicit none type(test_type), intent(inout) :: this deallocate( this%foo ) end subroutine destroy_test !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !> @brief A more sensible place to document. !> @details But it does not appear. !> @param teapot Some other argument. !> subroutine wobble( this, teapot ) implicit none class(test_type), intent(in) :: this integer, intent(in) :: teapot write( output_unit, '("wobble ", I0)' ) teapot end subroutine wobble !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! subroutine wubble( this, cheese ) implicit none class(test_type), intent(in) :: this integer, intent(in) :: cheese write( output_unit, '("wubble ", I0)' ) cheese end subroutine wubble !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! subroutine wibble_integer( this, value ) implicit none class(test_type), intent(inout) :: this integer, intent(in) :: value write( output_unit, '("wibble ", I0)' ) value end subroutine wibble_integer !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !> @brief Again I would like to document this here. !> @details But again it will not show up. !> @param value A floating point argument. !> subroutine wibble_real( this, value ) implicit none class(test_type), intent(inout) :: this real, intent(in) :: value write( output_unit, '("wibble ", F14.4)' ) value end subroutine wibble_real end module test_mod Running this through Doxygen I get the following messages: test_mod.f90:29: warning: Member wubble (function) of class test_mod::test_type is not documented. Of course it is, but at the definition rather than the declaration. test_mod.f90:30: warning: Member wibble=> wibble_integer, wibble_real (function) of class test_mod::test_type is not documented. This is sort of true except wibble is documented by wibble_integer and wibble_real. test_mod.f90:38: warning: Member wibble_real (function) of class test_mod::test_type is not documented. It is, but further down. test_mod.f90:40: warning: Member destroy_test (function) of class test_mod::test_type is not documented. Again, it is, but further down. test_mod.f90:13: warning: Member foo (variable) of class test_mod::test_type is not documented. True but irrelevant to the current issue. test_mod.f90:22: warning: argument 'teapot' of command @param is not found in the argument list of test_mod::test_type::wobble() It does, but at definition, not declaration. I realise that this is all pretty esoteric stuff and that there isn't a lot of object Fortran around but if you can suggest a solution I would be very grateful. |
From: Albert <alb...@gm...> - 2016-09-22 13:55:11
|
Matthew, Thank you for the example. I see indeed a feature tthat is not supported yet in doxygen: generic, public :: wibble => wibble_integer, wibble_real It will take a it of time before I can have a good look at this problem. Albert On Thu, Sep 22, 2016 at 3:45 PM, Hambley, Matthew < mat...@me...> wrote: > From: Albert [mailto:alb...@gm...] > > > > Can you create a small example to show the short comings? > > Of course. What follows is a Fortran module which should illustrate what I > am trying to describe. (Object Fortran is, sadly, never short) > > Having carefully laid it out I suddenly had a nasty realisation that > Outlook is probably about to mangle it horrible so I've attached a copy as > well. Skip past the source code for commentary. > > module test_mod > > use iso_fortran_env, only : output_unit > > implicit none > > private > > !> @brief Type which does a thing > !> @details Documented where we would expect. > !> > type, public :: test_type > > private > > integer, allocatable :: foo(:) > > contains > > private > !> @brief Document in the type declaration > !> @details Not so good as there are no arguments here. If they are > !> documented here they show up in documentation but Doxygen > !> complains about them being documented but not existing. Of > !> course they do, but further down. > !> > !> Regardless the documentation is separate from the > !> implementation. > !> @param teapot Some argument. > !> > procedure, public :: wobble > procedure, public :: wubble > generic, public :: wibble => wibble_integer, wibble_real > > !> @brief One aspect of wibble > !> @details I can document this here but it appears as a method of > !> the type whereas really it should appear under > !> "wibble". After all, it is private and not part of the > !> API. > !> > procedure wibble_integer > procedure wibble_real > > final :: destroy_test > > end type test_type > > interface test_type > procedure create_test_default > !> @brief Specific initialiser > !> @details Will this how up? No it will not. > procedure create_test_specific > end interface test_type > > contains > > !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! > !> @brief Default initialiser > !> > !> @details It would be nice to document this here but it wont show up. > !> > function create_test_default() result(new_test) > > implicit none > > type(test_type) :: new_test > > allocate( new_test%foo(10) ) > end function create_test_default > > !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! > function create_test_specific( tally ) result(new_test) > > implicit none > > integer, intent(in) :: tally > > type(test_type) :: new_test > > allocate( new_test%foo(tally) ) > > end function create_test_specific > > !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! > !!!!!!!!!!!!! > !> @brief Destructor. > !> @details Would prefer to document this here. > !> > subroutine destroy_test( this ) > > implicit none > type(test_type), intent(inout) :: this > > deallocate( this%foo ) > > end subroutine destroy_test > > !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! > !!!!!!!!!!!!! > !> @brief A more sensible place to document. > !> @details But it does not appear. > !> @param teapot Some other argument. > !> > subroutine wobble( this, teapot ) > > implicit none > > class(test_type), intent(in) :: this > integer, intent(in) :: teapot > > write( output_unit, '("wobble ", I0)' ) teapot > > end subroutine wobble > > !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! > !!!!!!!!!!!!! > subroutine wubble( this, cheese ) > > implicit none > > class(test_type), intent(in) :: this > integer, intent(in) :: cheese > > write( output_unit, '("wubble ", I0)' ) cheese > > end subroutine wubble > > !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! > !!!!!!!!!!!!! > subroutine wibble_integer( this, value ) > > implicit none > > class(test_type), intent(inout) :: this > integer, intent(in) :: value > > write( output_unit, '("wibble ", I0)' ) value > > end subroutine wibble_integer > > !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! > !!!!!!!!!!!!! > !> @brief Again I would like to document this here. > !> @details But again it will not show up. > !> @param value A floating point argument. > !> > subroutine wibble_real( this, value ) > > implicit none > > class(test_type), intent(inout) :: this > real, intent(in) :: value > > write( output_unit, '("wibble ", F14.4)' ) value > > end subroutine wibble_real > > end module test_mod > > Running this through Doxygen I get the following messages: > > test_mod.f90:29: warning: Member wubble (function) of class > test_mod::test_type is not documented. > > Of course it is, but at the definition rather than the declaration. > > test_mod.f90:30: warning: Member wibble=> wibble_integer, wibble_real > (function) of class test_mod::test_type is not documented. > > This is sort of true except wibble is documented by wibble_integer and > wibble_real. > > test_mod.f90:38: warning: Member wibble_real (function) of class > test_mod::test_type is not documented. > > It is, but further down. > > test_mod.f90:40: warning: Member destroy_test (function) of class > test_mod::test_type is not documented. > > Again, it is, but further down. > > test_mod.f90:13: warning: Member foo (variable) of class > test_mod::test_type is not documented. > > True but irrelevant to the current issue. > > test_mod.f90:22: warning: argument 'teapot' of command @param is not found > in the argument list of test_mod::test_type::wobble() > > It does, but at definition, not declaration. > > I realise that this is all pretty esoteric stuff and that there isn't a > lot of object Fortran around but if you can suggest a solution I would be > very grateful. > |
From: Hambley, M. <mat...@me...> - 2016-10-10 10:46:51
|
From: Albert [mailto:alb...@gm...] > > Thank you for the example. > > I see indeed a feature tthat is not supported yet in doxygen: > generic, public :: wibble => wibble_integer, wibble_real > > It will take a it of time before I can have a good look at this > problem. While we would like a solution to these issues at some point, most of our code is written in Fortran 90 style so these problems don't arise. So we are happy to wait until it is convenient for you. You don't explicitly address it so can you confirm that you understand the issue regarding the placement of argument documentation. That type-bound procedures can be documented in the type declaration but not their arguments as they do not appear there. Meanwhile they can't be documented at the procedure definitions where the arguments do appear. -- Matthew Hambley Scientific Software Engineer Met Office Hadley Centre, Exeter, UK |