feat(def-navigation): surface last-loaded .def declaration for hover/GoTo
When a block template or address is declared in multiple PSC layers, hover and Go to Definition now resolve to the effective declaration (the one from the last-loaded .def file). Find References and Rename still include all declarations. - add effective_def_locations(documents, target, uris) helper (returns the last declaration) - use effective_def_locations in lsp_server for goto/definition endpoints - change def_hover_markdown to show the effective declaration and append a short "_Overrides ..._" note listing overridden declarations - update changelog and add a test that verifies hover/GoTo reference the last loaded declaration while references include all declarations
This commit is contained in:
@@ -240,3 +240,50 @@ def test_def_rename_updates_tcl_callers(tmp_path, monkeypatch):
|
||||
edits = {Path(uri).name: [(e.range.start.line, e.range.start.character) for e in items] for uri, items in edit.changes.items()}
|
||||
assert edits == {"caller.tcl": [(1, 20)], "service.def": [(14, 19)]}
|
||||
assert lsp_server.def_rename(_def_params(def_file, "steady_rest", newName="bad name")) is None
|
||||
|
||||
|
||||
LAYERED_PSC = """<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Configuration>
|
||||
<Sourcing><Sequence>
|
||||
<Layer Name="Controller" SubFolder="ctrl"><DefinedEvents><Filename Name="ctrl"/></DefinedEvents></Layer>
|
||||
<Layer Name="OEM" SubFolder="oem"><DefinedEvents><Filename Name="oem"/></DefinedEvents></Layer>
|
||||
</Sequence></Sourcing>
|
||||
</Configuration>
|
||||
"""
|
||||
|
||||
|
||||
def test_template_in_several_layers_shows_the_last_loaded_one(tmp_path, monkeypatch):
|
||||
for folder, text in (("ctrl", "Text[M17]"), ("oem", "Text[RET]")):
|
||||
(tmp_path / folder).mkdir()
|
||||
(tmp_path / folder / f"{folder}.def").write_text(
|
||||
f"MACHINE X\n\nFORMATTING\n{{\n BLOCK_TEMPLATE end_of_subprogram\n {{\n {text}\n }}\n}}\n", encoding="utf-8"
|
||||
)
|
||||
(tmp_path / "post.psc").write_text(LAYERED_PSC, encoding="utf-8")
|
||||
source = "MOM_do_template end_of_subprogram\n"
|
||||
caller = tmp_path / "caller.tcl"
|
||||
caller.write_text(source, encoding="utf-8")
|
||||
server = TclLanguageServer(name="def-layer-test", version="1", max_workers=1)
|
||||
server.protocol._workspace = Workspace( # pylint: disable=protected-access
|
||||
root_uri=tmp_path.as_uri(),
|
||||
sync_kind=lsp.TextDocumentSyncKind.Incremental,
|
||||
workspace_folders=[lsp.WorkspaceFolder(uri=tmp_path.as_uri(), name="root")],
|
||||
position_encoding=lsp.PositionEncodingKind.Utf16,
|
||||
)
|
||||
monkeypatch.setattr(lsp_server, "LSP_SERVER", server)
|
||||
server.refresh_psc_scripts([tmp_path])
|
||||
server.workspace.put_text_document(lsp.TextDocumentItem(uri=caller.as_uri(), language_id="tcl", version=1, text=source))
|
||||
server.update_poco_completion_for_file(server.workspace.get_text_document(caller.as_uri()))
|
||||
document = lsp.TextDocumentIdentifier(uri=caller.as_uri())
|
||||
position = lsp.Position(line=0, character=20)
|
||||
|
||||
hover = lsp_server.hover(lsp.HoverParams(text_document=document, position=position)).contents.value
|
||||
assert hover.startswith("**Block template** `end_of_subprogram` — oem.def:5")
|
||||
assert "Text[RET]" in hover and "Text[M17]" not in hover
|
||||
assert hover.endswith("_Overrides ctrl.def:5_")
|
||||
|
||||
[location] = lsp_server.goto_definition(lsp.DefinitionParams(text_document=document, position=position))
|
||||
assert location.uri.endswith("oem/oem.def")
|
||||
references = lsp_server.references(
|
||||
lsp.ReferenceParams(text_document=document, position=position, context=lsp.ReferenceContext(include_declaration=True))
|
||||
)
|
||||
assert {Path(location.uri).name for location in references} == {"ctrl.def", "oem.def", "caller.tcl"}
|
||||
|
||||
Reference in New Issue
Block a user