feat(server/lsp_tclserver): index .def symbols and provide completion items
This commit is contained in:
@@ -18,7 +18,8 @@ from tools import checks, incremental_parse, parser
|
|||||||
from tools.completion_items import CompletionCollector
|
from tools.completion_items import CompletionCollector
|
||||||
from tools.tcloo_symbols import class_completion_items
|
from tools.tcloo_symbols import class_completion_items
|
||||||
from tools.tcloo_completion import indexed_classes
|
from tools.tcloo_completion import indexed_classes
|
||||||
from tools.file_sourcing import get_all_psc_files, psc_script_files
|
from tools.def_symbols import DefSymbols, read_def_symbols
|
||||||
|
from tools.file_sourcing import get_all_psc_files, psc_defined_event_files, psc_script_files
|
||||||
from tools.formatter import NxFormatter as Formatter
|
from tools.formatter import NxFormatter as Formatter
|
||||||
from tools.index_cache import FileStat, IndexCache, file_stat
|
from tools.index_cache import FileStat, IndexCache, file_stat
|
||||||
from tools.inlay_hint import InlayHintSignature, build_custom_inlay_signatures
|
from tools.inlay_hint import InlayHintSignature, build_custom_inlay_signatures
|
||||||
@@ -61,6 +62,8 @@ class TclLanguageServer(LanguageServer):
|
|||||||
self.psc_script_paths: list[str] = []
|
self.psc_script_paths: list[str] = []
|
||||||
self._psc_files: dict[str, list[pathlib.Path]] = {}
|
self._psc_files: dict[str, list[pathlib.Path]] = {}
|
||||||
self._psc_lock = threading.RLock()
|
self._psc_lock = threading.RLock()
|
||||||
|
# .def path -> BLOCK_TEMPLATE/ADDRESS names, in PSC DefinedEvents order.
|
||||||
|
self.def_symbols: dict[str, DefSymbols] = {}
|
||||||
self.navigation_indexes: dict[str, FileSymbolIndex] = {}
|
self.navigation_indexes: dict[str, FileSymbolIndex] = {}
|
||||||
self.variable_indexes: dict[
|
self.variable_indexes: dict[
|
||||||
str,
|
str,
|
||||||
@@ -252,8 +255,48 @@ class TclLanguageServer(LanguageServer):
|
|||||||
classes.update(indexes.get(self._normalized_path(path), {}))
|
classes.update(indexes.get(self._normalized_path(path), {}))
|
||||||
return classes
|
return classes
|
||||||
|
|
||||||
|
def refresh_def_symbols(self, roots, report=LOGGER.warning):
|
||||||
|
"""Read the block templates and addresses of all .def files listed as PSC DefinedEvents."""
|
||||||
|
symbols: dict[str, DefSymbols] = {}
|
||||||
|
for root in roots:
|
||||||
|
for psc in get_all_psc_files(root):
|
||||||
|
try:
|
||||||
|
def_files = psc_defined_event_files(psc)
|
||||||
|
except (OSError, ET.ParseError) as error:
|
||||||
|
report(f"Could not read PSC {psc}: {error}")
|
||||||
|
continue
|
||||||
|
for def_file in def_files:
|
||||||
|
if str(def_file) in symbols:
|
||||||
|
continue
|
||||||
|
try:
|
||||||
|
symbols[str(def_file)] = read_def_symbols(def_file)
|
||||||
|
except OSError as error:
|
||||||
|
report(f"Could not read DEF file {def_file}: {error}")
|
||||||
|
with self._index_lock:
|
||||||
|
self.def_symbols = symbols
|
||||||
|
|
||||||
|
def _def_symbol_items(self, attribute: str, kind, description: str) -> list[lsp.CompletionItem]:
|
||||||
|
with self._index_lock:
|
||||||
|
symbols = dict(self.def_symbols)
|
||||||
|
return [
|
||||||
|
lsp.CompletionItem(
|
||||||
|
label=name,
|
||||||
|
kind=kind,
|
||||||
|
detail=f"{description} ({pathlib.Path(path).name})",
|
||||||
|
)
|
||||||
|
for path, def_symbols in symbols.items()
|
||||||
|
for name in getattr(def_symbols, attribute)
|
||||||
|
]
|
||||||
|
|
||||||
|
def block_template_items(self) -> list[lsp.CompletionItem]:
|
||||||
|
return self._def_symbol_items("block_templates", lsp.CompletionItemKind.Struct, "Block template")
|
||||||
|
|
||||||
|
def address_items(self) -> list[lsp.CompletionItem]:
|
||||||
|
return self._def_symbol_items("addresses", lsp.CompletionItemKind.Field, "Address")
|
||||||
|
|
||||||
def refresh_psc_scripts(self, roots, report=LOGGER.warning):
|
def refresh_psc_scripts(self, roots, report=LOGGER.warning):
|
||||||
"""Index PSC dependencies through the same pipeline as workspace procs."""
|
"""Index PSC dependencies through the same pipeline as workspace procs."""
|
||||||
|
self.refresh_def_symbols(roots, report=report)
|
||||||
with self._psc_lock:
|
with self._psc_lock:
|
||||||
discovered = {}
|
discovered = {}
|
||||||
for root in roots:
|
for root in roots:
|
||||||
|
|||||||
Reference in New Issue
Block a user