From bfdd912d93b853f54422b3bff7796e9dea9d801d Mon Sep 17 00:00:00 2001 From: Aaron Zuspan Date: Sun, 11 Aug 2024 18:16:04 -0700 Subject: [PATCH] Differentiate constants and variables --- src/spinasm_lsp/parser.py | 2 ++ src/spinasm_lsp/server.py | 12 ++++++++++-- tests/conftest.py | 13 +++++++++---- tests/test_server.py | 10 +++++++++- 4 files changed, 30 insertions(+), 7 deletions(-) diff --git a/src/spinasm_lsp/parser.py b/src/spinasm_lsp/parser.py index 8723f66..a429247 100644 --- a/src/spinasm_lsp/parser.py +++ b/src/spinasm_lsp/parser.py @@ -207,6 +207,8 @@ def __init__(self, source: str): efunc=lambda *args, **kwargs: None, ) + # Track which symbols were defined at initialization, e.g. registers and LFOs + self.constants: list[str] = list(self.symtbl.keys()) # Keep an unchanged copy of the original source self._source: list[str] = self.source.copy() diff --git a/src/spinasm_lsp/server.py b/src/spinasm_lsp/server.py index 8be1b43..b43d9c7 100644 --- a/src/spinasm_lsp/server.py +++ b/src/spinasm_lsp/server.py @@ -98,9 +98,13 @@ def _get_defined_hover(stxt: str, parser: SPINAsmParser) -> str: if stxt in parser.jmptbl: hover_definition = parser.jmptbl[stxt] return f"(label) {stxt}: Offset[{hover_definition}]" - if stxt in parser.symtbl: + # Check constants next since they are also defined in symtbl + if stxt in parser.constants: hover_definition = parser.symtbl[stxt] return f"(constant) {stxt}: Literal[{hover_definition}]" + if stxt in parser.symtbl: + hover_definition = parser.symtbl[stxt] + return f"(variable) {stxt}: Literal[{hover_definition}]" return "" @@ -154,6 +158,8 @@ async def completions( lsp.CompletionItem( label=symbol, kind=lsp.CompletionItemKind.Constant + if symbol in parser.constants + else lsp.CompletionItemKind.Variable if symbol in parser.symtbl else lsp.CompletionItemKind.Module, detail=_get_defined_hover(symbol, parser=parser), @@ -216,7 +222,9 @@ async def document_symbol_definitions( name=symbol, kind=lsp.SymbolKind.Module if symbol in parser.jmptbl - else lsp.SymbolKind.Constant, + # There's no need to check for constants here since they aren't included + # in the parser definitions. + else lsp.SymbolKind.Variable, range=definition, selection_range=definition, ) diff --git a/tests/conftest.py b/tests/conftest.py index 07b22c0..207952b 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -56,7 +56,7 @@ class RenameDict(TypedDict): { # Variable "symbol": "apout", - "kind": lsp.SymbolKind.Constant, + "kind": lsp.SymbolKind.Variable, "range": lsp.Range( start=lsp.Position(line=23, character=4), end=lsp.Position(line=23, character=9), @@ -65,7 +65,7 @@ class RenameDict(TypedDict): { # Memory "symbol": "lap2a", - "kind": lsp.SymbolKind.Constant, + "kind": lsp.SymbolKind.Variable, "range": lsp.Range( start=lsp.Position(line=16, character=4), end=lsp.Position(line=16, character=9), @@ -157,12 +157,17 @@ class RenameDict(TypedDict): { "symbol": "mono", "position": lsp.Position(line=47, character=5), - "contains": "(constant) MONO: Literal[32]", + "contains": "(variable) MONO: Literal[32]", + }, + { + "symbol": "reg0", + "position": lsp.Position(line=22, character=9), + "contains": "(constant) REG0: Literal[32]", }, { "symbol": "lap2b#", "position": lsp.Position(line=73, character=4), - "contains": "(constant) LAP2B#: Literal[9802]", + "contains": "(variable) LAP2B#: Literal[9802]", }, { # CHO RDA, hovering over CHO diff --git a/tests/test_server.py b/tests/test_server.py index d65f11d..9003ee5 100644 --- a/tests/test_server.py +++ b/tests/test_server.py @@ -86,12 +86,20 @@ async def test_completions(client: LanguageClient): # Completions for defined values should show their literal value apout_completion = [item for item in results.items if item.label == "APOUT"][0] - assert apout_completion.detail == "(constant) APOUT: Literal[33]" + assert apout_completion.detail == "(variable) APOUT: Literal[33]" + assert apout_completion.kind == lsp.CompletionItemKind.Variable assert apout_completion.documentation is None + # Completions for constant values should show their literal value + reg0_completion = [item for item in results.items if item.label == "REG0"][0] + assert reg0_completion.detail == "(constant) REG0: Literal[32]" + assert reg0_completion.kind == lsp.CompletionItemKind.Constant + assert reg0_completion.documentation is None + # Completions for opcodes should include their documentation cho_rda_completion = [item for item in results.items if item.label == "CHO RDA"][0] assert cho_rda_completion.detail == "(opcode)" + assert cho_rda_completion.kind == lsp.CompletionItemKind.Function assert "## `CHO RDA N, C, D`" in str(cho_rda_completion.documentation)