Skip to content

Commit

Permalink
Merge branch 'master' into pre-commit-ci-update-config
Browse files Browse the repository at this point in the history
  • Loading branch information
gnikit authored May 17, 2023
2 parents 57be310 + 6a82432 commit 942d9a8
Show file tree
Hide file tree
Showing 7 changed files with 73 additions and 11 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@

### 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))
- Fixed end of scope for `CRITICAL` keyword blocks
([#255](https://github.com/fortran-lang/fortls/issues/255))
- Fixed bug where completion of interfaces in USE ONLY would produce the snippet
Expand Down
8 changes: 3 additions & 5 deletions fortls/helper_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -582,7 +582,7 @@ def get_var_stack(line: str) -> list[str]:
return None


def fortran_md(code: str, docs: str | None, langid: str = "fortran90"):
def fortran_md(code: str, docs: str | None):
"""Convert Fortran code to markdown
Parameters
Expand All @@ -591,17 +591,15 @@ def fortran_md(code: str, docs: str | None, langid: str = "fortran90"):
Fortran code
docs : str | None
Documentation string
langid : str, optional
Language ID, by default 'fortran90'
Returns
-------
str
Markdown string
"""
msg = ""
if code:
msg = f"```{langid}\n{code}\n```"
msg = "```{langid}\n" # This gets inserted later
msg += f"{code}\n```"
# Add documentation
if docs: # if docs is not None or ""
msg += f"\n-----\n{docs}"
Expand Down
38 changes: 33 additions & 5 deletions fortls/langserver.py
Original file line number Diff line number Diff line change
Expand Up @@ -514,9 +514,14 @@ def build_comp(
if call_sig is not None:
comp_obj["detail"] += " " + call_sig
# Use the full markdown documentation
hover_msg = candidate.get_hover_md(long=True)
hover_msg: str = candidate.get_hover_md(long=True)
if hover_msg:
hover_msg = {"kind": "markdown", "value": hover_msg}
hover_msg: dict = {
"kind": "markdown",
"value": hover_msg.replace(
"```{langid}", f"```{self.hover_language}", 1
),
}
comp_obj["documentation"] = hover_msg
return comp_obj

Expand Down Expand Up @@ -837,6 +842,17 @@ def check_optional(arg, params: dict):
return i
return None

def replace_langid(params: list[dict]) -> list[dict]:
new_params = params[:]
for param in new_params:
if "documentation" not in param:
continue
# Replace the first value of langid, when starting a code block
param["documentation"]["value"] = param["documentation"][
"value"
].replace("```{langid}", f"```{self.hover_language}", 1)
return params

# Get parameters from request
params: dict = request["params"]
uri: str = params["textDocument"]["uri"]
Expand Down Expand Up @@ -904,6 +920,9 @@ def check_optional(arg, params: dict):
label, doc_str, params = var_obj.get_signature()
if label is None:
return None
# Replace placeholder language id with Fortran ID
params = replace_langid(params)

# Find current parameter by index or by
# looking at last arg with optional name
param_num = len(arg_strings) - 1
Expand All @@ -917,6 +936,7 @@ def check_optional(arg, params: dict):
param_num = opt_num
signature = {"label": label, "parameters": params}
if doc_str is not None:
doc_str = doc_str.format(langid=self.hover_language)
signature["documentation"] = {"kind": "markdown", "value": doc_str}
req_dict = {"signatures": [signature], "activeParameter": param_num}
return req_dict
Expand Down Expand Up @@ -1063,7 +1083,7 @@ def serve_hover(self, request: dict):
def create_hover(string: str, docs: str | None):
# This does not account for Fixed Form Fortran, but it should be
# okay for 99% of cases
return fortran_md(string, docs, self.hover_language)
return fortran_md(string, docs).format(langid=self.hover_language)

# Get parameters from request
params: dict = request["params"]
Expand All @@ -1087,7 +1107,11 @@ def create_hover(string: str, docs: str | None):
MODULE_TYPE_ID,
CLASS_TYPE_ID,
):
hover_array.append(var_obj.get_hover_md(long=True))
hover_array.append(
var_obj.get_hover_md(long=True).replace(
"```{langid}", f"```{self.hover_language}", 1
)
)
elif var_type == INTERFACE_TYPE_ID:
for member in var_obj.mems:
hover_str, docs = member.get_hover(long=True)
Expand All @@ -1097,7 +1121,11 @@ def create_hover(string: str, docs: str | None):
# Unless we have a Fortran literal include the desc in the hover msg
# See get_definition for an explanation about this default name
if not var_obj.desc.startswith(FORTRAN_LITERAL):
hover_array.append(var_obj.get_hover_md(long=True))
hover_array.append(
var_obj.get_hover_md(long=True).replace(
"```{langid}", f"```{self.hover_language}", 1
)
)
# Hover for Literal variables
elif var_obj.desc.endswith("REAL"):
hover_array.append(create_hover("REAL", None))
Expand Down
5 changes: 5 additions & 0 deletions fortls/objects.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
):
Expand All @@ -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
Expand Down
3 changes: 2 additions & 1 deletion fortls/parse_fortran.py
Original file line number Diff line number Diff line change
Expand Up @@ -1493,14 +1493,15 @@ 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,
obj_info.name,
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,
)
Expand Down
14 changes: 14 additions & 0 deletions test/test_server_hover.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
10 changes: 10 additions & 0 deletions test/test_source/hover/associate_block_2.f90
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit 942d9a8

Please sign in to comment.