ford icon indicating copy to clipboard operation
ford copied to clipboard

Problems with public methods in derived type

Open patflynngithub opened this issue 1 year ago • 2 comments

Have problems with how public methods of a derived type are displayed in FORD-generated doc.

Code correctness verified with gfortran. Note: workarounds attempted are in Fortran code comments.

!> mod_external module
module mod_external

implicit none

private

public external_class_t

! public :: output_int_ext
! public :: output_real_generic_ext
! public :: output_complex_generic_ext

!> type definition in external_class_t class
type external_class_t

private

contains

   !> procedure declaration inside external_class_t class
   procedure :: output_int_ext
   ! procedure, public :: output_int_ext
   
   generic :: output_generic_ext => output_real_generic_ext, & 
                                    output_complex_generic_ext
      procedure :: output_real_generic_ext
      procedure :: output_complex_generic_ext

end type external_class_t

! public :: output_int_ext
! public :: output_real_generic_ext
! public :: output_complex_generic_ext

contains

!> subroutine output_int method of external_class_t in mod_external module
subroutine output_int_ext(this, an_int)

   implicit none

   class(external_class_t), intent(in) :: this
   integer, intent(in)                 :: an_int     !! dummy variable declaration mod_external

   write (*,*) "an_int = ", an_int

end subroutine output_int_ext

!> subroutine output_real_generic_ext method of external_class_t in mod_external module
subroutine output_real_generic_ext(this, a_real)

   implicit none

   class(external_class_t), intent(in) :: this
   real, intent(in)                 :: a_real     !! dummy variable declaration mod_external

   write (*,*) "a_real = ", a_real

end subroutine output_real_generic_ext

!> subroutine output_complex_generic_ext method of external_class_t in mod_external module
subroutine output_complex_generic_ext(this, a_complex)

   implicit none

   class(external_class_t), intent(in) :: this
   complex, intent(in)                 :: a_complex     !! dummy variable declaration mod_external

   write (*,*) "a_complex = ", a_complex

end subroutine output_complex_generic_ext

end module mod_external

Problems

  • the public methods (public by default) are not showing up
    • in Procedures section of main webpage
    • on Procedures webpage
  • they are showing up on Modules/mod_external (but not in the Subroutines section) and Derived Types/external_class_t webpages
    • but on external_class_t webpage, the output_int_ext method shows up as "header" public and "body" private
      • same is true for the generic and non-generic entries for output_real_generic_ext and output_complex_generic_ext methods

Workaround

  • tried adding public attribute to method declaration in derived type contains sections
    • e.g., procedure, public :: output_int_ext
    • doesn't help
  • added public statements for the methods in the specification part of the module (not inside derived type)
    • i.e.,
              public :: output_int_ext
              public :: output_real_generic_ext
              public :: output_complex_generic_ext
      
    • WORKED
      • solves all above problems, but AFAIK shouldn't have to do this

(FORD version 6.2.4)

patflynngithub avatar Apr 26 '23 21:04 patflynngithub

If I understand correctly, I think this is the expected behaviour. Type bound procedures will only display the docs for the binding and not for the implementation. See #450 for some discussion of this.

If you want to have separate pages for the procedures themselves, then they either have to be public or you can put ! display: public, private in the module docstring.

ZedThree avatar Apr 27 '23 08:04 ZedThree

I don't understand the bindings/implementation distinctions made in #450. Your suggestion of !> display: public, private doesn't seem to work for me (I tried putting in on the module, derived type, and method headers).

As I said above, to get the type-bound procedures to appear on the main and Procedures webpages, I have the workaround of putting

public :: output_int_ext
public :: output_real_generic_ext
public :: output_complex_generic_ext

in the module specifications section (but not inside the derived type itself). However, it seems odd that I have to do this, when these procedures are already public by default.

patflynngithub avatar Apr 27 '23 21:04 patflynngithub