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:
@@ -338,3 +338,27 @@ def derived_def_symbol(
|
||||
targets.extend(target for variable in variables for target in scope_targets.get(variable, ()))
|
||||
kinds = frozenset(kind for target in targets for kind in _target_kinds(target, table, namespace))
|
||||
return (kinds, *literal) if kinds else None
|
||||
|
||||
|
||||
def _all_commands(node: Node) -> Iterator[Command]:
|
||||
for child in getattr(node, "children", []):
|
||||
if isinstance(child, Command):
|
||||
yield child
|
||||
yield from _all_commands(child)
|
||||
|
||||
|
||||
def unknown_def_names(tree: Node, declared: dict[str, frozenset[str]]) -> list[tuple[str, str, lsp.Range]]:
|
||||
"""Literal NX command arguments naming a block template or address no .def file declares.
|
||||
|
||||
``declared`` maps each kind to its declared names; kinds without any
|
||||
declaration are not checked, since their .def file is not loaded.
|
||||
"""
|
||||
unknown = []
|
||||
for command in _all_commands(tree):
|
||||
for node, kind in def_argument_kinds(command):
|
||||
names = declared.get(kind)
|
||||
name = def_name(node) if names else None
|
||||
if name is not None and name not in names:
|
||||
line, column = node.contents_pos
|
||||
unknown.append((kind, name, _range(line, column, name)))
|
||||
return unknown
|
||||
|
||||
Reference in New Issue
Block a user