From 59f440267a2b97170d4384e5f84300ef434db384 Mon Sep 17 00:00:00 2001 From: gnikit Date: Wed, 17 May 2023 00:15:13 +0100 Subject: [PATCH] fix: associate block from Function result I think the signature is still not ideal i.e. `LOGICAL FUNCTION` but I chose it since it indicates that the associate block variable is the result of a function. Fixes #269 --- CHANGELOG.md | 3 +++ fortls/objects.py | 5 +++++ fortls/parse_fortran.py | 3 ++- test/test_server_hover.py | 14 ++++++++++++++ test/test_source/hover/associate_block_2.f90 | 10 ++++++++++ 5 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 test/test_source/hover/associate_block_2.f90 diff --git a/CHANGELOG.md b/CHANGELOG.md index 8cdfbe1e..935d35c0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,9 @@ ### Fixed +- Fixed bug where `associate` blocks for variables pointing to function results + where not properly resolved + ([#269](https://github.com/fortran-lang/fortls/issues/269)) - Fixed bug where the `langid` was not propagated correctly from the user settings to the LSP creation stage for all types of requests. ([#257](https://github.com/fortran-lang/fortls/issues/257)) diff --git a/fortls/objects.py b/fortls/objects.py index b44d1362..4daf7b91 100644 --- a/fortls/objects.py +++ b/fortls/objects.py @@ -1160,6 +1160,7 @@ def __init__( args: str = "", mod_flag: bool = False, keywords: list = None, + keyword_info: dict = None, result_type: str = None, result_name: str = None, ): @@ -1173,9 +1174,13 @@ def __init__( self.result_name: str = result_name self.result_type: str = result_type self.result_obj: Variable = None + self.keyword_info: dict = keyword_info # Set the implicit result() name to be the function name if self.result_name is None: self.result_name = self.name + # Used in Associated blocks + if self.keyword_info is None: + self.keyword_info = {} def copy_interface(self, copy_source: Function): # Call the parent class method diff --git a/fortls/parse_fortran.py b/fortls/parse_fortran.py index 9c47c3b6..fa1d9dfe 100644 --- a/fortls/parse_fortran.py +++ b/fortls/parse_fortran.py @@ -1493,7 +1493,7 @@ def parse( log.debug("%s !!! SUBROUTINE - Ln:%d", line, line_no) elif obj_type == "fun": - keywords, _ = map_keywords(obj_info.keywords) + keywords, keyword_info = map_keywords(obj_info.keywords) new_fun = Function( file_ast, line_no, @@ -1501,6 +1501,7 @@ def parse( args=obj_info.args, mod_flag=obj_info.mod_flag, keywords=keywords, + keyword_info=keyword_info, result_type=obj_info.result.type, result_name=obj_info.result.name, ) diff --git a/test/test_server_hover.py b/test/test_server_hover.py index ba52dbe3..f1a79147 100644 --- a/test/test_server_hover.py +++ b/test/test_server_hover.py @@ -366,6 +366,20 @@ def test_hover_block(): validate_hover(results, ref_results) +def test_associate_block_func_result(): + string = write_rpc_request(1, "initialize", {"rootPath": str(test_dir / "hover")}) + file_path = test_dir / "hover" / "associate_block_2.f90" + string += hover_req(file_path, 2, 14) + string += hover_req(file_path, 3, 9) + errorcode, results = run_request(string, fortls_args=["--sort_keywords", "-n", "1"]) + assert errorcode == 0 + ref_results = [ + "```fortran90\nLOGICAL FUNCTION :: hi\n```", + "```fortran90\nLOGICAL FUNCTION :: hi\n```", + ] + validate_hover(results, ref_results) + + def test_hover_submodule_procedure(): """Test that submodule procedures and functions with modifier keywords are correctly displayed when hovering. diff --git a/test/test_source/hover/associate_block_2.f90 b/test/test_source/hover/associate_block_2.f90 new file mode 100644 index 00000000..3649f18f --- /dev/null +++ b/test/test_source/hover/associate_block_2.f90 @@ -0,0 +1,10 @@ +program associate_block_2 + implicit none + associate (hi => say_hi()) + if (hi) print *, 'Bye' + end associate +contains + logical function say_hi() + say_hi = .true. + end +end program