Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@

### Fixed

- Fixed bug where Go To Implementation would not work for submodules
([#74](https://github.com/fortran-lang/fortls/issues/74))
- Fixed bug where `associate` blocks for variables pointing to function results
where not properly resolved
([#269](https://github.com/fortran-lang/fortls/issues/269))
Expand Down
4 changes: 4 additions & 0 deletions fortls/langserver.py
Original file line number Diff line number Diff line change
Expand Up @@ -1165,6 +1165,10 @@ def serve_implementation(self, request: dict):
impl_obj = var_obj.link_obj
if (impl_obj is not None) and (impl_obj.file_ast.file is not None):
return self._create_ref_link(impl_obj)
elif var_obj.parent.get_type() == INTERFACE_TYPE_ID:
# Find the first implementation of the interface
if var_obj.link_obj is not None:
return self._create_ref_link(var_obj.link_obj)
return None

def serve_rename(self, request: dict):
Expand Down
3 changes: 3 additions & 0 deletions fortls/objects.py
Original file line number Diff line number Diff line change
Expand Up @@ -897,6 +897,8 @@ def resolve_link(self, obj_tree):
if file_scope is child_old:
child.file_ast.scope_list[j] = child
if child.get_type() == prototype.get_type():
# Link the interface with the implementation
prototype.link_obj = child
prototype.resolve_link(obj_tree)
child.copy_interface(prototype)
break
Expand All @@ -922,6 +924,7 @@ def __init__(
self.in_children: list = []
self.missing_args: list = []
self.mod_scope: bool = mod_flag
self.link_obj: Subroutine | Function | None = None

def is_mod_scope(self):
return self.mod_scope
Expand Down
15 changes: 15 additions & 0 deletions test/test_server_implementation.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,3 +75,18 @@ def test_implementation_no_file():
errcode, results = run_request(string, ["-n", "1"])
assert errcode == 0
assert results[1] is None


def test_implementation_submodule():
"""Go to implementation for submodule"""
root = test_dir / "imp"
string = write_rpc_request(1, "initialize", {"rootPath": str(root)})
file_path = root / "submodule.f90"
string += imp_request(file_path, 5, 30)
string += imp_request(file_path, 8, 30)
string += imp_request(file_path, 9, 30)
errcode, results = run_request(string, ["-n", "1"])
assert errcode == 0
assert results[1] == create(str(root / "submodule.f90"), 19, 20, 34)
assert results[2] == create(str(root / "submodule.f90"), 19, 20, 34)
assert results[3] is None
24 changes: 24 additions & 0 deletions test/test_source/imp/submodule.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
module parent_mod
implicit none
type :: typ
real(kind=8) :: value
contains
procedure :: method1 => submod_method1
end type typ
interface
module subroutine submod_method1(this)
class(typ), intent(inout) :: this
end subroutine submod_method1
module subroutine submod_method2(this, value)
class(typ), intent(inout) :: this
real, intent(in) :: value
end subroutine submod_method2
end interface
end module parent_mod
submodule(parent_mod) submod
contains
module subroutine submod_method1(this)
class(typ), intent(inout) :: this
this%value = 0
end subroutine submod_method1
end submodule submod