add new semantic tokens
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
import enum
|
import enum
|
||||||
from typing import List
|
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
|
from tclint.commands import get_commands
|
||||||
import attrs
|
import attrs
|
||||||
from common.load_data import standard_items
|
from common.load_data import standard_items
|
||||||
@@ -14,6 +14,9 @@ class TokenModifier(enum.IntFlag):
|
|||||||
definition = enum.auto()
|
definition = enum.auto()
|
||||||
declaration = enum.auto()
|
declaration = enum.auto()
|
||||||
builtin = enum.auto()
|
builtin = enum.auto()
|
||||||
|
globalvar = enum.auto()
|
||||||
|
reference = enum.auto()
|
||||||
|
write = enum.auto()
|
||||||
|
|
||||||
|
|
||||||
@attrs.define
|
@attrs.define
|
||||||
@@ -101,6 +104,10 @@ class _Highlighter(Visitor):
|
|||||||
if in_custom or in_standard:
|
if in_custom or in_standard:
|
||||||
line, col = routine.contents_pos
|
line, col = routine.contents_pos
|
||||||
self._tokens.append((((line - 1, col - 1), len(name), "function", [])))
|
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":
|
if routine.contents == "puts":
|
||||||
line, col = routine.contents_pos
|
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:
|
if routine.contents == "set" and command.args:
|
||||||
first_arg = command.args[0]
|
first_arg = command.args[0]
|
||||||
token_info = self._get_token_info(first_arg)
|
token_info = self._get_token_info(first_arg)
|
||||||
if token_info:
|
if token_info:
|
||||||
(line, col), length = token_info
|
(line, col), length = token_info
|
||||||
self._tokens.append(
|
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
|
||||||
(line, col),
|
if len(command.args) == 1 and token_info:
|
||||||
length,
|
(line, col), length = token_info
|
||||||
"variable",
|
mods = [TokenModifier.reference]
|
||||||
[TokenModifier.declaration],
|
# 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:
|
if routine.contents == "proc" and command.args:
|
||||||
first_arg = command.args[0]
|
first_arg = command.args[0]
|
||||||
if hasattr(first_arg, "pos") and hasattr(first_arg, "value"):
|
if hasattr(first_arg, "pos") and hasattr(first_arg, "value"):
|
||||||
@@ -153,11 +159,12 @@ class _Highlighter(Visitor):
|
|||||||
# Parameter kann einfaches Wort sein
|
# Parameter kann einfaches Wort sein
|
||||||
if hasattr(child, "value") and child.value is not None:
|
if hasattr(child, "value") and child.value is not None:
|
||||||
line, col = child.pos
|
line, col = child.pos
|
||||||
|
# Parameters are variables (locals): mark as variable with declaration
|
||||||
self._tokens.append(
|
self._tokens.append(
|
||||||
(
|
(
|
||||||
(line - 1, col - 1),
|
(line - 1, col - 1),
|
||||||
len(child.value),
|
len(child.value),
|
||||||
"parameter",
|
"variable",
|
||||||
[TokenModifier.declaration],
|
[TokenModifier.declaration],
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@@ -171,7 +178,7 @@ class _Highlighter(Visitor):
|
|||||||
(
|
(
|
||||||
(line - 1, col - 1),
|
(line - 1, col - 1),
|
||||||
len(name_node.value),
|
len(name_node.value),
|
||||||
"parameter",
|
"variable",
|
||||||
[TokenModifier.declaration],
|
[TokenModifier.declaration],
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@@ -181,6 +188,17 @@ class _Highlighter(Visitor):
|
|||||||
line, col = first_arg.pos
|
line, col = first_arg.pos
|
||||||
self._tokens.append((((line - 1, col - 1), len(first_arg.value), "class", [])))
|
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]:
|
def tokens(self) -> list[Token]:
|
||||||
"""Encode tokens as described in
|
"""Encode tokens as described in
|
||||||
https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_semanticTokens.
|
https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_semanticTokens.
|
||||||
|
|||||||
Reference in New Issue
Block a user