Skip to content

Commit 27b9d49

Browse files
authored
Merge pull request #324 from fortran-lang/refactor/objetcs
Refactoring Fortran Objects
2 parents a096d8e + 5b6acfc commit 27b9d49

File tree

4 files changed

+361
-349
lines changed

4 files changed

+361
-349
lines changed

fortls/helper_functions.py

+76-45
Original file line numberDiff line numberDiff line change
@@ -100,10 +100,9 @@ def strip_line_label(line: str) -> tuple[str, str | None]:
100100
match = FRegex.LINE_LABEL.match(line)
101101
if match is None:
102102
return line, None
103-
else:
104-
line_label = match.group(1)
105-
out_str = line[: match.start(1)] + " " * len(line_label) + line[match.end(1) :]
106-
return out_str, line_label
103+
line_label = match.group(1)
104+
out_str = line[: match.start(1)] + " " * len(line_label) + line[match.end(1) :]
105+
return out_str, line_label
107106

108107

109108
def strip_strings(in_line: str, maintain_len: bool = False) -> str:
@@ -172,7 +171,7 @@ def separate_def_list(test_str: str) -> list[str] | None:
172171
if curr_str != "":
173172
def_list.append(curr_str)
174173
curr_str = ""
175-
elif (curr_str == "") and (len(def_list) == 0):
174+
elif not def_list:
176175
return None
177176
continue
178177
curr_str += char
@@ -198,17 +197,20 @@ def find_word_in_line(line: str, word: str) -> Range:
198197
start and end positions (indices) of the word if not found it returns
199198
-1, len(word) -1
200199
"""
201-
i = -1
202-
for poss_name in FRegex.WORD.finditer(line):
203-
if poss_name.group() == word:
204-
i = poss_name.start()
205-
break
200+
i = next(
201+
(
202+
poss_name.start()
203+
for poss_name in FRegex.WORD.finditer(line)
204+
if poss_name.group() == word
205+
),
206+
-1,
207+
)
206208
# TODO: if i == -1: return None makes more sense
207209
return Range(i, i + len(word))
208210

209211

210212
def find_paren_match(string: str) -> int:
211-
"""Find matching closing parenthesis **from an already open parenthesis scope**
213+
"""Find matching closing parenthesis from an already open parenthesis scope
212214
by forward search of the string, returns -1 if no match is found
213215
214216
Parameters
@@ -237,15 +239,14 @@ def find_paren_match(string: str) -> int:
237239
-1
238240
"""
239241
paren_count = 1
240-
ind = -1
241242
for i, char in enumerate(string):
242243
if char == "(":
243244
paren_count += 1
244245
elif char == ")":
245246
paren_count -= 1
246247
if paren_count == 0:
247248
return i
248-
return ind
249+
return -1
249250

250251

251252
def get_line_prefix(
@@ -282,17 +283,16 @@ def get_line_prefix(
282283
col += len(prepend_string)
283284
line_prefix = curr_line[:col].lower()
284285
# Ignore string literals
285-
if qs:
286-
if (line_prefix.find("'") > -1) or (line_prefix.find('"') > -1):
287-
sq_count = 0
288-
dq_count = 0
289-
for char in line_prefix:
290-
if (char == "'") and (dq_count % 2 == 0):
291-
sq_count += 1
292-
elif (char == '"') and (sq_count % 2 == 0):
293-
dq_count += 1
294-
if (dq_count % 2 == 1) or (sq_count % 2 == 1):
295-
return None
286+
if qs and ((line_prefix.find("'") > -1) or (line_prefix.find('"') > -1)):
287+
sq_count = 0
288+
dq_count = 0
289+
for char in line_prefix:
290+
if (char == "'") and (dq_count % 2 == 0):
291+
sq_count += 1
292+
elif (char == '"') and (sq_count % 2 == 0):
293+
dq_count += 1
294+
if (dq_count % 2 == 1) or (sq_count % 2 == 1):
295+
return None
296296
return line_prefix
297297

298298

@@ -329,14 +329,12 @@ def resolve_globs(glob_path: str, root_path: str = None) -> list[str]:
329329
>>> resolve_globs('test') == [str(pathlib.Path(os.getcwd()) / 'test')]
330330
True
331331
"""
332-
# Resolve absolute paths i.e. not in our root_path
333-
if os.path.isabs(glob_path) or not root_path:
334-
p = Path(glob_path).resolve()
335-
root = p.anchor # drive letter + root path
336-
rel = str(p.relative_to(root)) # contains glob pattern
337-
return [str(p.resolve()) for p in Path(root).glob(rel)]
338-
else:
332+
if not os.path.isabs(glob_path) and root_path:
339333
return [str(p.resolve()) for p in Path(root_path).resolve().glob(glob_path)]
334+
p = Path(glob_path).resolve()
335+
root = p.anchor # drive letter + root path
336+
rel = str(p.relative_to(root)) # contains glob pattern
337+
return [str(p.resolve()) for p in Path(root).glob(rel)]
340338

341339

342340
def only_dirs(paths: list[str]) -> list[str]:
@@ -406,7 +404,9 @@ def map_keywords(keywords: list[str]):
406404
return mapped_keywords, keyword_info
407405

408406

409-
def get_keywords(keywords: list, keyword_info: dict = {}):
407+
def get_keywords(keywords: list, keyword_info: dict = None):
408+
if keyword_info is None:
409+
keyword_info = {}
410410
keyword_strings = []
411411
for keyword_id in keywords:
412412
string_rep = KEYWORD_LIST[keyword_id]
@@ -461,10 +461,7 @@ def get_paren_substring(string: str) -> str | None:
461461
"""
462462
i1 = string.find("(")
463463
i2 = string.rfind(")")
464-
if -1 < i1 < i2:
465-
return string[i1 + 1 : i2]
466-
else:
467-
return None
464+
return string[i1 + 1 : i2] if -1 < i1 < i2 else None
468465

469466

470467
def get_paren_level(line: str) -> tuple[str, list[Range]]:
@@ -496,7 +493,7 @@ def get_paren_level(line: str) -> tuple[str, list[Range]]:
496493
('', [Range(start=0, end=0)])
497494
498495
"""
499-
if line == "":
496+
if not line:
500497
return "", [Range(0, 0)]
501498
level = 0
502499
in_string = False
@@ -526,9 +523,7 @@ def get_paren_level(line: str) -> tuple[str, list[Range]]:
526523
if level == 0:
527524
sections.append(Range(i, i1))
528525
sections.reverse()
529-
out_string = ""
530-
for section in sections:
531-
out_string += line[section.start : section.end]
526+
out_string = "".join(line[section.start : section.end] for section in sections)
532527
return out_string, sections
533528

534529

@@ -564,7 +559,7 @@ def get_var_stack(line: str) -> list[str]:
564559
>>> get_var_stack('')
565560
['']
566561
"""
567-
if len(line) == 0:
562+
if not line:
568563
return [""]
569564
final_var, sections = get_paren_level(line)
570565
if final_var == "":
@@ -574,10 +569,9 @@ def get_var_stack(line: str) -> list[str]:
574569
for i, section in enumerate(sections):
575570
if not line[section.start : section.end].strip().startswith("%"):
576571
iLast = i
577-
final_var = ""
578-
for section in sections[iLast:]:
579-
final_var += line[section.start : section.end]
580-
572+
final_var = "".join(
573+
line[section.start : section.end] for section in sections[iLast:]
574+
)
581575
if final_var is not None:
582576
final_var = "%".join([i.strip() for i in final_var.split("%")])
583577
final_op_split: list[str] = FRegex.OBJBREAK.split(final_var)
@@ -586,6 +580,43 @@ def get_var_stack(line: str) -> list[str]:
586580
return None
587581

588582

583+
def get_placeholders(arg_list: list[str]) -> tuple[str, str]:
584+
"""
585+
Function used to generate placeholders for snippets
586+
587+
Parameters
588+
----------
589+
arg_list : list[str]
590+
Method arguments list
591+
592+
Returns
593+
-------
594+
Tuple[str, str]
595+
Tuple of arguments as a string and snippet string
596+
597+
Examples
598+
--------
599+
>>> get_placeholders(['x', 'y'])
600+
('(x, y)', '(${1:x}, ${2:y})')
601+
602+
>>> get_placeholders(['x=1', 'y=2'])
603+
('(x=1, y=2)', '(x=${1:1}, y=${2:2})')
604+
605+
>>> get_placeholders(['x', 'y=2', 'z'])
606+
('(x, y=2, z)', '(${1:x}, y=${2:2}, ${3:z})')
607+
"""
608+
place_holders = []
609+
for i, arg in enumerate(arg_list):
610+
opt_split = arg.split("=")
611+
if len(opt_split) > 1:
612+
place_holders.append(f"{opt_split[0]}=${{{i+1}:{opt_split[1]}}}")
613+
else:
614+
place_holders.append(f"${{{i+1}:{arg}}}")
615+
arg_str = f"({', '.join(arg_list)})"
616+
arg_snip = f"({', '.join(place_holders)})"
617+
return arg_str, arg_snip
618+
619+
589620
def fortran_md(code: str, docs: str | None):
590621
"""Convert Fortran code to markdown
591622

fortls/intrinsics.py

+10-20
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@
33
import glob
44
import json
55
import os
6+
import pathlib
67

7-
from fortls.helper_functions import fortran_md, map_keywords
8+
from fortls.helper_functions import fortran_md, get_placeholders, map_keywords
89
from fortls.objects import (
910
FortranAST,
1011
FortranObj,
@@ -26,9 +27,7 @@ def set_lowercase_intrinsics():
2627

2728

2829
def intrinsics_case(name: str, args: str):
29-
if lowercase_intrinsics:
30-
return name.lower(), args.lower()
31-
return name, args
30+
return (name.lower(), args.lower()) if lowercase_intrinsics else (name, args)
3231

3332

3433
class Intrinsic(FortranObj):
@@ -68,19 +67,13 @@ def get_snippet(self, name_replace=None, drop_arg=-1):
6867
arg_snip = None
6968
else:
7069
arg_list = self.args.split(",")
71-
arg_str, arg_snip = self.get_placeholders(arg_list)
72-
name = self.name
73-
if name_replace is not None:
74-
name = name_replace
75-
snippet = None
76-
if arg_snip is not None:
77-
snippet = name + arg_snip
70+
arg_str, arg_snip = get_placeholders(arg_list)
71+
name = name_replace if name_replace is not None else self.name
72+
snippet = name + arg_snip if arg_snip is not None else None
7873
return name + arg_str, snippet
7974

8075
def get_signature(self):
81-
arg_sigs = []
82-
for arg in self.args.split(","):
83-
arg_sigs.append({"label": arg})
76+
arg_sigs = [{"label": arg} for arg in self.args.split(",")]
8477
call_sig, _ = self.get_snippet()
8578
return call_sig, self.doc_str, arg_sigs
8679

@@ -89,13 +82,11 @@ def get_hover(self, long=False):
8982

9083
def get_hover_md(self, long=False):
9184
msg, docs = self.get_hover(long)
92-
msg = msg if msg else ""
85+
msg = msg or ""
9386
return fortran_md(msg, docs)
9487

9588
def is_callable(self):
96-
if self.type == 2:
97-
return True
98-
return False
89+
return self.type == 2
9990

10091

10192
def load_intrinsics():
@@ -281,8 +272,7 @@ def update_m_intrinsics():
281272
for f in sorted(files):
282273
key = f.replace("M_intrinsics/md/", "")
283274
key = key.replace(".md", "").upper() # remove md extension
284-
with open(f) as md_f:
285-
val = md_f.read()
275+
val = pathlib.Path(f).read_text()
286276
# remove manpage tag
287277
val = val.replace(f"**{key.lower()}**(3)", f"**{key.lower()}**")
288278
val = val.replace(f"**{key.upper()}**(3)", f"**{key.upper()}**")

fortls/json_templates.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ def range_json(sln: int, sch: int, eln: int = None, ech: int = None):
1010
}
1111

1212

13-
def diagnostic_json(sln: int, sch: int, eln: int, ech: int, msg: str, sev: str):
13+
def diagnostic_json(sln: int, sch: int, eln: int, ech: int, msg: str, sev: int):
1414
return {**range_json(sln, sch, eln, ech), "message": msg, "severity": sev}
1515

1616

0 commit comments

Comments
 (0)