feat(tcloo): add document-local TclOO completions, signature help and hints
Add conservative, document-local TclOO type inference and tooling so the server can offer method completions, signature help, and inlay parameter hints for statically resolvable TclOO receivers (including `new`/`create`, `my`, and simple return-chains). Also surface class names as completion items and emit semantic tokens for class declarations/references. Notable changes: - New tcloo_* tools: completion, symbols, and argument parsing; integrated into on_completion, signature_help, inlay hint generation and semantic token highlighting. Completions are returned early when an OO receiver context is detected. - Use a completion-friendly parser fallback when the main AST fails (TclSyntaxError) so editing-in-progress code still yields useful completions. - Add CompletionItemKind.Class to command kinds, exclude class items from the poco completion name cache, and include new unit tests for the TclOO helpers.
This commit is contained in:
@@ -75,6 +75,10 @@ from tools.semantic_tokens import (
|
||||
_Highlighter,
|
||||
)
|
||||
from tools.signature_help import build_signature_help
|
||||
from tools.tcloo_arguments import method_signature_help
|
||||
from tclint.lexer import TclSyntaxError
|
||||
from tools.tcloo_completion import parse_completion_source, tcloo_completions
|
||||
from tools.tcloo_symbols import class_completion_items
|
||||
from tools.tcl_command_completion import (
|
||||
TCL_COMMAND_ITEMS,
|
||||
TCL_COMMAND_NAMES,
|
||||
@@ -278,6 +282,9 @@ def on_completion(params: lsp.CompletionParams) -> lsp.CompletionList:
|
||||
doc = LSP_SERVER.workspace.get_text_document(params.text_document.uri)
|
||||
position = params.position
|
||||
source_lines = LSP_SERVER.get_lines(doc)
|
||||
oo_items = tcloo_completions(source_lines, position)
|
||||
if oo_items is not None:
|
||||
return lsp.CompletionList(is_incomplete=False, items=oo_items)
|
||||
array_items = array_element_completions(
|
||||
source_lines, position, LSP_SERVER.navigation_snapshot().values(),
|
||||
str(pathlib.Path(uris.to_fs_path(doc.uri))),
|
||||
@@ -334,7 +341,12 @@ def on_completion(params: lsp.CompletionParams) -> lsp.CompletionList:
|
||||
):
|
||||
return lsp.CompletionList(is_incomplete=False, items=[])
|
||||
|
||||
tree = LSP_SERVER.get_tree(doc)
|
||||
try:
|
||||
tree = LSP_SERVER.get_tree(doc)
|
||||
except TclSyntaxError:
|
||||
tree = parse_completion_source(doc.source)
|
||||
if tree is None:
|
||||
return lsp.CompletionList(is_incomplete=False, items=[])
|
||||
globals_set, procs_locals, proc_ranges = LSP_SERVER.variable_index_for_document(
|
||||
doc, tree
|
||||
)
|
||||
@@ -347,6 +359,7 @@ def on_completion(params: lsp.CompletionParams) -> lsp.CompletionList:
|
||||
break
|
||||
|
||||
candidates: list[tuple[int, lsp.CompletionItem]] = []
|
||||
candidates.extend((0, item) for item in class_completion_items(tree))
|
||||
for name in sorted(local_names - globals_set):
|
||||
candidates.append(
|
||||
(
|
||||
@@ -457,7 +470,15 @@ def on_completion(params: lsp.CompletionParams) -> lsp.CompletionList:
|
||||
)
|
||||
def signature_help(params: lsp.SignatureHelpParams) -> lsp.SignatureHelp | None:
|
||||
document = LSP_SERVER.workspace.get_text_document(params.text_document.uri)
|
||||
tree = LSP_SERVER.get_tree(document)
|
||||
method_help = method_signature_help(document.source, params.position)
|
||||
if method_help is not None:
|
||||
return method_help
|
||||
try:
|
||||
tree = LSP_SERVER.get_tree(document)
|
||||
except TclSyntaxError:
|
||||
tree = parse_completion_source(document.source)
|
||||
if tree is None:
|
||||
return None
|
||||
|
||||
custom_signatures, custom_docs = LSP_SERVER.proc_metadata_snapshot(
|
||||
document.path
|
||||
@@ -541,6 +562,7 @@ def semantic_tokens(params: lsp.SemanticTokensParams):
|
||||
|
||||
# Reuse cached AST
|
||||
tree = LSP_SERVER.get_tree(document)
|
||||
hl.highlight_classes(tree)
|
||||
tree.accept(hl, recurse=True)
|
||||
|
||||
tokens = hl.tokens()
|
||||
|
||||
Reference in New Issue
Block a user