Skip to content

Commit 4d0cc66

Browse files
committed
rework handling keywords from resource files with duplicate names, fixes #43
1 parent 57e7c8c commit 4d0cc66

File tree

2 files changed

+124
-106
lines changed

2 files changed

+124
-106
lines changed

robotcode/language_server/robotframework/diagnostics/namespace.py

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1010,7 +1010,7 @@ async def _import(
10101010
)
10111011

10121012
if allready_imported_resources is None and entry.library_doc.source != self.source:
1013-
self._resources[entry.alias or entry.name or entry.import_name] = entry
1013+
self._resources[entry.import_name] = entry
10141014
try:
10151015
await self._import_imports(
10161016
entry.imports,
@@ -1043,7 +1043,7 @@ async def _import(
10431043
allready_imported_resources is not None
10441044
and allready_imported_resources.library_doc.source
10451045
):
1046-
self._resources[entry.alias or entry.name or entry.import_name] = entry
1046+
self._resources[entry.import_name] = entry
10471047

10481048
await self.append_diagnostics(
10491049
range=entry.import_range,
@@ -1278,9 +1278,20 @@ async def get_imported_variables_libdoc(self, name: str, args: Tuple[str, ...] =
12781278
)
12791279

12801280
@_logger.call
1281-
async def get_keywords(self) -> List[KeywordDoc]:
1281+
async def iter_all_keywords(self) -> AsyncGenerator[KeywordDoc, None]:
12821282
import itertools
12831283

1284+
libdoc = await self.get_library_doc()
1285+
1286+
for doc in itertools.chain(
1287+
*(e.library_doc.keywords.values() for e in self._libraries.values()),
1288+
*(e.library_doc.keywords.values() for e in self._resources.values()),
1289+
libdoc.keywords.values() if libdoc is not None else [],
1290+
):
1291+
yield doc
1292+
1293+
@_logger.call
1294+
async def get_keywords(self) -> List[KeywordDoc]:
12841295
if self._keywords is None:
12851296
async with self._keywords_lock:
12861297
if self._keywords is None:
@@ -1291,17 +1302,11 @@ async def get_keywords(self) -> List[KeywordDoc]:
12911302
await self.ensure_initialized()
12921303

12931304
result: Dict[KeywordMatcher, KeywordDoc] = {}
1294-
libdoc = await self.get_library_doc()
12951305

12961306
i = 0
1297-
for name, doc in itertools.chain(
1298-
*(e.library_doc.keywords.items() for e in self._libraries.values()),
1299-
*(e.library_doc.keywords.items() for e in self._resources.values()),
1300-
libdoc.keywords.items() if libdoc is not None else [],
1301-
):
1307+
async for doc in self.iter_all_keywords():
13021308
i += 1
1303-
# if not any(k for k in result.keys() if k == name):
1304-
result[KeywordMatcher(name)] = doc
1309+
result[KeywordMatcher(doc.name)] = doc
13051310

13061311
self._keywords = list(result.values())
13071312
finally:

robotcode/language_server/robotframework/parts/completion.py

Lines changed: 108 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
cast,
2222
)
2323

24-
from ....utils.async_itertools import async_chain, async_chain_iterator
24+
from ....utils.async_itertools import async_chain, async_chain_iterator, async_next
2525
from ....utils.async_tools import threaded
2626
from ....utils.logging import LoggingDescriptor
2727
from ...common.decorators import language_id, trigger_characters
@@ -325,13 +325,11 @@ async def resolve(self, completion_item: CompletionItem) -> CompletionItem:
325325
kind=MarkupKind.MARKDOWN, value=f"Error:\n{e}"
326326
)
327327
elif type in [CompleteResultKind.KEYWORD.name]:
328-
libname = completion_item.data.get("libname", None)
329-
name = completion_item.data.get("name", None)
330-
331-
if libname is not None and name is not None:
328+
id = completion_item.data.get("id", None)
329+
if id is not None:
332330
try:
333-
kw_doc = next(
334-
(kw for kw in await self.namespace.get_keywords() if kw.name == name),
331+
kw_doc = await async_next(
332+
(kw async for kw in self.namespace.iter_all_keywords() if hash(kw) == id),
335333
None,
336334
)
337335

@@ -511,104 +509,118 @@ def enumerate_indexes(s: str, c: str) -> Iterator[int]:
511509
for kw in libraries[library_name].library_doc.keywords.values():
512510
if kw.is_error_handler:
513511
continue
514-
c = CompletionItem(
515-
label=kw.name,
516-
kind=CompletionItemKind.FUNCTION,
517-
detail=CompleteResultKind.KEYWORD.value,
518-
sort_text=f"020_{kw.name}",
519-
insert_text_format=InsertTextFormat.PLAINTEXT,
520-
text_edit=TextEdit(range=r, new_text=kw.name) if r is not None else None,
521-
data={
522-
"document_uri": str(self.document.uri),
523-
"type": CompleteResultKind.KEYWORD.name,
524-
"libname": kw.libname,
525-
"name": kw.name,
526-
},
512+
result.append(
513+
CompletionItem(
514+
label=kw.name,
515+
kind=CompletionItemKind.FUNCTION,
516+
detail=f"{CompleteResultKind.KEYWORD.value} {f'({kw.libname})' if kw.libname is not None else ''}",
517+
sort_text=f"020_{kw.name}",
518+
insert_text_format=InsertTextFormat.PLAINTEXT,
519+
text_edit=TextEdit(range=r, new_text=kw.name) if r is not None else None,
520+
data={
521+
"document_uri": str(self.document.uri),
522+
"type": CompleteResultKind.KEYWORD.name,
523+
"libname": kw.libname,
524+
"name": kw.name,
525+
"id": hash(kw),
526+
},
527+
)
527528
)
528-
result.append(c)
529529

530-
resources = await self.namespace.get_resources()
531-
if library_name in resources:
530+
resources = {
531+
k: v
532+
for k, v in (await self.namespace.get_resources()).items()
533+
if library_name_matcher == KeywordMatcher(v.name)
534+
}
535+
536+
if resources:
532537
r.start.character = lib_name_index + 1
533-
for kw in resources[library_name].library_doc.keywords.values():
534-
if kw.is_error_handler:
535-
continue
536-
c = CompletionItem(
537-
label=kw.name,
538-
kind=CompletionItemKind.FUNCTION,
539-
detail=CompleteResultKind.KEYWORD.value,
540-
sort_text=f"020_{kw.name}",
541-
insert_text_format=InsertTextFormat.PLAINTEXT,
542-
text_edit=TextEdit(range=r, new_text=kw.name) if r is not None else None,
543-
data={
544-
"document_uri": str(self.document.uri),
545-
"type": CompleteResultKind.KEYWORD.name,
546-
"libname": kw.libname,
547-
"name": kw.name,
548-
},
549-
)
550-
result.append(c)
538+
for res in resources.values():
539+
for kw in res.library_doc.keywords.values():
540+
if kw.is_error_handler:
541+
continue
542+
result.append(
543+
CompletionItem(
544+
label=kw.name,
545+
kind=CompletionItemKind.FUNCTION,
546+
detail=f"{CompleteResultKind.KEYWORD.value} {f'({kw.libname})' if kw.libname is not None else ''}",
547+
sort_text=f"020_{kw.name}",
548+
insert_text_format=InsertTextFormat.PLAINTEXT,
549+
text_edit=TextEdit(range=r, new_text=kw.name) if r is not None else None,
550+
data={
551+
"document_uri": str(self.document.uri),
552+
"type": CompleteResultKind.KEYWORD.name,
553+
"libname": kw.libname,
554+
"name": kw.name,
555+
"id": hash(kw),
556+
},
557+
)
558+
)
551559

552560
return result
553561

554562
for kw in await self.namespace.get_keywords():
555563
if kw.is_error_handler:
556564
continue
557565

558-
c = CompletionItem(
559-
label=kw.name,
560-
kind=CompletionItemKind.FUNCTION,
561-
detail=f"{CompleteResultKind.KEYWORD.value} {f'({kw.libname})' if kw.libname is not None else ''}",
562-
deprecated=kw.is_deprecated,
563-
sort_text=f"020_{kw.name}",
564-
insert_text_format=InsertTextFormat.PLAINTEXT,
565-
text_edit=TextEdit(range=r, new_text=kw.name) if r is not None else None,
566-
data={
567-
"document_uri": str(self.document.uri),
568-
"type": CompleteResultKind.KEYWORD.name,
569-
"libname": kw.libname,
570-
"name": kw.name,
571-
},
566+
result.append(
567+
CompletionItem(
568+
label=kw.name,
569+
kind=CompletionItemKind.FUNCTION,
570+
detail=f"{CompleteResultKind.KEYWORD.value} {f'({kw.libname})' if kw.libname is not None else ''}",
571+
deprecated=kw.is_deprecated,
572+
sort_text=f"020_{kw.name}",
573+
insert_text_format=InsertTextFormat.PLAINTEXT,
574+
text_edit=TextEdit(range=r, new_text=kw.name) if r is not None else None,
575+
data={
576+
"document_uri": str(self.document.uri),
577+
"type": CompleteResultKind.KEYWORD.name,
578+
"libname": kw.libname,
579+
"name": kw.name,
580+
"id": hash(kw),
581+
},
582+
)
572583
)
573-
result.append(c)
574584

575585
for k, v in (await self.namespace.get_libraries()).items():
576-
c = CompletionItem(
577-
label=k,
578-
kind=CompletionItemKind.MODULE,
579-
detail="Library",
580-
sort_text=f"030_{k}",
581-
deprecated=v.library_doc.is_deprecated,
582-
insert_text_format=InsertTextFormat.PLAINTEXT,
583-
text_edit=TextEdit(range=r, new_text=k) if r is not None else None,
584-
data={
585-
"document_uri": str(self.document.uri),
586-
"type": CompleteResultKind.MODULE.name,
587-
"name": k,
588-
"import_name": v.import_name,
589-
"args": v.args,
590-
"alias": v.alias,
591-
},
586+
result.append(
587+
CompletionItem(
588+
label=k,
589+
kind=CompletionItemKind.MODULE,
590+
detail="Library",
591+
sort_text=f"030_{v.name}",
592+
deprecated=v.library_doc.is_deprecated,
593+
insert_text_format=InsertTextFormat.PLAINTEXT,
594+
text_edit=TextEdit(range=r, new_text=k) if r is not None else None,
595+
data={
596+
"document_uri": str(self.document.uri),
597+
"type": CompleteResultKind.MODULE.name,
598+
"name": v.name,
599+
"import_name": v.import_name,
600+
"args": v.args,
601+
"alias": v.alias,
602+
},
603+
)
592604
)
593-
result.append(c)
594605

595606
for k, v in (await self.namespace.get_resources()).items():
596-
c = CompletionItem(
597-
label=k,
598-
kind=CompletionItemKind.MODULE,
599-
detail="Resource",
600-
deprecated=v.library_doc.is_deprecated,
601-
sort_text=f"030_{k}",
602-
insert_text_format=InsertTextFormat.PLAINTEXT,
603-
text_edit=TextEdit(range=r, new_text=k) if r is not None else None,
604-
data={
605-
"document_uri": str(self.document.uri),
606-
"type": CompleteResultKind.RESOURCE.name,
607-
"name": v.name,
608-
"import_name": v.import_name,
609-
},
607+
result.append(
608+
CompletionItem(
609+
label=v.name,
610+
kind=CompletionItemKind.MODULE,
611+
detail="Resource",
612+
deprecated=v.library_doc.is_deprecated,
613+
sort_text=f"030_{v.name}",
614+
insert_text_format=InsertTextFormat.PLAINTEXT,
615+
text_edit=TextEdit(range=r, new_text=v.name) if r is not None else None,
616+
data={
617+
"document_uri": str(self.document.uri),
618+
"type": CompleteResultKind.RESOURCE.name,
619+
"name": k,
620+
"import_name": v.import_name,
621+
},
622+
)
610623
)
611-
result.append(c)
612624

613625
if add_none:
614626
result.append(
@@ -623,14 +635,15 @@ def enumerate_indexes(s: str, c: str) -> Iterator[int]:
623635

624636
if add_reserverd:
625637
for k in get_reserved_keywords():
626-
c = CompletionItem(
627-
label=k,
628-
kind=CompletionItemKind.KEYWORD,
629-
sort_text=f"999_{k}",
630-
insert_text_format=InsertTextFormat.PLAINTEXT,
631-
text_edit=TextEdit(range=r, new_text=k) if r is not None else None,
638+
result.append(
639+
CompletionItem(
640+
label=k,
641+
kind=CompletionItemKind.KEYWORD,
642+
sort_text=f"999_{k}",
643+
insert_text_format=InsertTextFormat.PLAINTEXT,
644+
text_edit=TextEdit(range=r, new_text=k) if r is not None else None,
645+
)
632646
)
633-
result.append(c)
634647

635648
return result
636649

0 commit comments

Comments
 (0)