hansec / fortran-language-server

Fortran Language Server for the Language Server Protocol
MIT License
295 stars 57 forks source link

Include parent types in completion list for components of derived-type variables #121

Open mscfd opened 5 years ago

mscfd commented 5 years ago

The completion request fortls --debug_rootpath . --debug_completion --debug_filepath test.f90 --debug_line 19 --debug_char 13 does not provide the two valid (implicit) components "feature_base" and "feature_ext" in the completion list.

test.f90

module mod

implicit none
private

type :: feature_base
end type feature_base

type, extends(feature_base) :: feature_ext
end type feature_ext

type, extends(feature_ext) :: feature_all
end type feature_all

contains

   subroutine xxx(x)
      class(feature_all) :: x
      x%feat

end module mod
hansec commented 5 years ago

Interesting, I've never seen that before. Just out of curiosity what is your use case for this feature? I guess there is value in being clear about "where" the value resides in the inheritance tree, but it seems like it is a little contradictory to the concept/usefulness of inheritance.

mscfd commented 5 years ago

I use it rarely but I have come across three use cases.

(1) If you extend the type of an existing old module (old style f90 code without methods) which you do not want to touch, and you want to call routines from this module, you explicitly need to upcast the type by extended_type%base_type in the calls.

(2) If you want to call a method from the parent type which has been overwritten in the type itself (like a destroy() cascade in the class hierarchy). This is pretty common in other languages (e.g. init cascades in python, but there you can change the type signature in contrast to fortran).

(3) If the concrete type controls the behaviour: If you have an object of a rich class you want to provide as an argument to a routine, which does fancy stuff for the rich class but only basic stuff for its base class from which it was derived, you need to explicitly downcast the type, if you need the basic behaviour.

edan-bainglass commented 3 years ago

Has this progressed at all? I find myself in need of case 2 (above) quite often. As mscfd mentioned, it is quite common when cascading calls and has some use even with Fortrans type signature limitation, e.g. create(), destroy(), etc.