add new semantic tokens
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import enum
|
||||
from typing import List
|
||||
from tclint.syntax_tree import Visitor, QuotedWord, Command, BareWord
|
||||
from tclint.syntax_tree import Visitor, QuotedWord, Command, BareWord, VarSub
|
||||
from tclint.commands import get_commands
|
||||
import attrs
|
||||
from common.load_data import standard_items
|
||||
@@ -14,6 +14,9 @@ class TokenModifier(enum.IntFlag):
|
||||
definition = enum.auto()
|
||||
declaration = enum.auto()
|
||||
builtin = enum.auto()
|
||||
globalvar = enum.auto()
|
||||
reference = enum.auto()
|
||||
write = enum.auto()
|
||||
|
||||
|
||||
@attrs.define
|
||||
@@ -101,6 +104,10 @@ class _Highlighter(Visitor):
|
||||
if in_custom or in_standard:
|
||||
line, col = routine.contents_pos
|
||||
self._tokens.append((((line - 1, col - 1), len(name), "function", [])))
|
||||
# Highlight 'global' itself as a keyword
|
||||
if name == "global":
|
||||
line, col = routine.contents_pos
|
||||
self._tokens.append((((line - 1, col - 1), len(name), "keyword", [])))
|
||||
|
||||
if routine.contents == "puts":
|
||||
line, col = routine.contents_pos
|
||||
@@ -114,21 +121,20 @@ class _Highlighter(Visitor):
|
||||
)
|
||||
)
|
||||
)
|
||||
# Variable declaration vs reference for 'set'
|
||||
if routine.contents == "set" and command.args:
|
||||
first_arg = command.args[0]
|
||||
token_info = self._get_token_info(first_arg)
|
||||
if token_info:
|
||||
(line, col), length = token_info
|
||||
self._tokens.append(
|
||||
(
|
||||
(
|
||||
(line, col),
|
||||
length,
|
||||
"variable",
|
||||
[TokenModifier.declaration],
|
||||
)
|
||||
)
|
||||
)
|
||||
mods = [TokenModifier.declaration, TokenModifier.write]
|
||||
self._tokens.append(((line, col), length, "variable", mods))
|
||||
# If there is exactly one argument, 'set var' is a read/reference
|
||||
if len(command.args) == 1 and token_info:
|
||||
(line, col), length = token_info
|
||||
mods = [TokenModifier.reference]
|
||||
# Mark as reference (read); remove write/declaration (keep simple: we still keep declaration above for consistency)
|
||||
self._tokens.append(((line, col), length, "variable", mods))
|
||||
if routine.contents == "proc" and command.args:
|
||||
first_arg = command.args[0]
|
||||
if hasattr(first_arg, "pos") and hasattr(first_arg, "value"):
|
||||
@@ -153,11 +159,12 @@ class _Highlighter(Visitor):
|
||||
# Parameter kann einfaches Wort sein
|
||||
if hasattr(child, "value") and child.value is not None:
|
||||
line, col = child.pos
|
||||
# Parameters are variables (locals): mark as variable with declaration
|
||||
self._tokens.append(
|
||||
(
|
||||
(line - 1, col - 1),
|
||||
len(child.value),
|
||||
"parameter",
|
||||
"variable",
|
||||
[TokenModifier.declaration],
|
||||
)
|
||||
)
|
||||
@@ -171,7 +178,7 @@ class _Highlighter(Visitor):
|
||||
(
|
||||
(line - 1, col - 1),
|
||||
len(name_node.value),
|
||||
"parameter",
|
||||
"variable",
|
||||
[TokenModifier.declaration],
|
||||
)
|
||||
)
|
||||
@@ -181,6 +188,17 @@ class _Highlighter(Visitor):
|
||||
line, col = first_arg.pos
|
||||
self._tokens.append((((line - 1, col - 1), len(first_arg.value), "class", [])))
|
||||
|
||||
# Highlight variables used via $var and $::var as references (read)
|
||||
for arg in getattr(command, "args", []):
|
||||
for child in getattr(arg, "children", []):
|
||||
if isinstance(child, VarSub) and hasattr(child, "pos") and child.value:
|
||||
line, col = child.pos
|
||||
# Determine if this looks like a global reference ($::var)
|
||||
mods = [TokenModifier.reference]
|
||||
if child.value.startswith("::"):
|
||||
mods.append(TokenModifier.globalvar)
|
||||
self._tokens.append((((line - 1, col - 1), len(child.value), "variable", mods)))
|
||||
|
||||
def tokens(self) -> list[Token]:
|
||||
"""Encode tokens as described in
|
||||
https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_semanticTokens.
|
||||
|
||||
Reference in New Issue
Block a user