feat(lsp): warn on undeclared block templates and addresses
Add diagnostics that warn when a literal NX command argument names a block template or address that no loaded .def file declares (diagnostic codes unknown-block-template and unknown-address). Names computed at runtime (e.g. $var or "CYCLE_$x") are not checked, and kinds whose .def file is not loaded are skipped. The server now recomputes and refreshes diagnostics when .def documents change (clears cached diagnostics and requests a workspace diagnostic refresh if the client supports it). Tests cover positive, negative and invalidated-cache cases.
This commit is contained in:
@@ -180,3 +180,44 @@ def test_derived_names_are_not_renamed(tmp_path, monkeypatch):
|
||||
text_document=lsp.TextDocumentIdentifier(uri=caller.as_uri()), position=_position("absolute_mode")
|
||||
)
|
||||
assert lsp_server.prepare_rename(params) is None
|
||||
|
||||
|
||||
def _warnings(server, tmp_path: Path, source: str):
|
||||
uri = (tmp_path / "check.tcl").as_uri()
|
||||
server.workspace.put_text_document(lsp.TextDocumentItem(uri=uri, language_id="tcl", version=1, text=source))
|
||||
diagnostics = server.lint(server.workspace.get_text_document(uri))
|
||||
return [
|
||||
(diagnostic.code, diagnostic.message, diagnostic.range.start.line, diagnostic.range.start.character, diagnostic.range.end.character)
|
||||
for diagnostic in diagnostics
|
||||
if diagnostic.code in {"unknown-block-template", "unknown-address"}
|
||||
]
|
||||
|
||||
|
||||
def test_unknown_template_and_address_are_warned(tmp_path, monkeypatch):
|
||||
server, _ = _project(tmp_path, monkeypatch)
|
||||
source = 'proc p {} {\n MOM_do_template stedy_rest\n MOM_force Once SPOS "SPSO"\n}\n'
|
||||
assert _warnings(server, tmp_path, source) == [
|
||||
("unknown-block-template", "Block template 'stedy_rest' is not declared in any loaded .def file", 1, 20, 30),
|
||||
("unknown-address", "Address 'SPSO' is not declared in any loaded .def file", 2, 25, 29),
|
||||
]
|
||||
|
||||
|
||||
def test_known_and_dynamic_names_are_not_warned(tmp_path, monkeypatch):
|
||||
server, _ = _project(tmp_path, monkeypatch)
|
||||
source = 'MOM_do_template steady_rest CREATE\nMOM_do_template $name\nMOM_do_template "CYCLE_$x"\nMOM_force Once SPOS\n'
|
||||
assert _warnings(server, tmp_path, source) == []
|
||||
|
||||
|
||||
def test_no_warnings_without_loaded_def_files(tmp_path, monkeypatch):
|
||||
server, _ = _project(tmp_path, monkeypatch)
|
||||
server.def_documents = {}
|
||||
assert _warnings(server, tmp_path, "MOM_do_template stedy_rest\n") == []
|
||||
|
||||
|
||||
def test_def_change_invalidates_cached_diagnostics(tmp_path, monkeypatch):
|
||||
server, caller = _project(tmp_path, monkeypatch)
|
||||
server.compute_diagnostics(server.workspace.get_text_document(caller.as_uri()))
|
||||
assert server.diagnostic_snapshot(caller.as_uri()) is not None
|
||||
(tmp_path / "service" / "service.def").write_text(DEF.replace("absolute_mode", "incremental_mode"), encoding="utf-8")
|
||||
server.refresh_def_symbols([tmp_path])
|
||||
assert server.diagnostic_snapshot(caller.as_uri()) is None
|
||||
|
||||
Reference in New Issue
Block a user