feat(lsp): leave moved variables and their members uncolored
Semantic tokens now drop a variable token whose name was moved before that line, and a property token whose base (`x` in `x.a`) is such a name. The transfer statement itself keeps its colors (moves on the same line are ignored for this filter), so only later uses turn plain/white. With _U2: own U = _U _U3: own U = _U2 print(_U2.a) line 3 emits only `print`; `_U2` and `a` have no semantic token. The move diagnostic still marks `_U2` separately. Completion filtering is unchanged (`_` offers only `_U3`).
This commit is contained in:
1 parent
6e6b94fdfb
commit
3b8dc1377d
1 file changed
+53
-4
@@ -9,6 +9,7 @@ import lib.lsp.LspSymbols as LspSymbols
|
||||
import lib.lsp.LspIndex as LspIndex
|
||||
import lib.lsp.LspWorkspace as LspWorkspace
|
||||
import lib.lsp.LspNavigation as LspNavigation
|
||||
import lib.lsp.LspChecks as LspChecks
|
||||
import lib.lsp.LspTransport as LspTransport
|
||||
import lib.lsp.LspRpc as LspRpc
|
||||
|
||||
@@ -329,8 +330,56 @@ def _SymbolTokenValid(pool: memhub.MemManager*, a: LspSymbols.LspAnalysis*,
|
||||
return 1 if string.strcmp(txt, name) == 0 else 0
|
||||
|
||||
|
||||
_sem_moved_line: int = -1
|
||||
_sem_moved: list[str]* = None
|
||||
|
||||
|
||||
def _IsIdentByte(ch: char) -> int:
|
||||
if ch >= 'a' and ch <= 'z': return 1
|
||||
if ch >= 'A' and ch <= 'Z': return 1
|
||||
if ch >= '0' and ch <= '9': return 1
|
||||
if ch == '_': return 1
|
||||
return 0
|
||||
|
||||
|
||||
def _MovedDrop(pool: memhub.MemManager*, a: LspSymbols.LspAnalysis*,
|
||||
t: LspSemToken*) -> int:
|
||||
"""1 when this token names a moved variable (or a member of one): keep it uncolored."""
|
||||
global _sem_moved_line, _sem_moved
|
||||
if t is None or t.typ < 0 or a is None or a.doc is None: return 0
|
||||
if t.typ != ST_VARIABLE and t.typ != ST_PROPERTY: return 0
|
||||
# Moves on the token's own line keep their color (the transfer statement itself).
|
||||
if t.sl != _sem_moved_line:
|
||||
_sem_moved = LspChecks.MovedBefore(pool, a, t.sl - 1)
|
||||
_sem_moved_line = t.sl
|
||||
if _sem_moved is None or int(len(_sem_moved)) == 0: return 0
|
||||
sb: int = LspSource.Utf16ColToByte(a.doc, t.sl, t.sc)
|
||||
eb: int = LspSource.Utf16ColToByte(a.doc, t.sl, t.ec)
|
||||
txt: str = LspSource.SliceBytes(pool, a.doc, t.sl, sb, t.sl, eb)
|
||||
if txt is not None and LspChecks._NameListFind(_sem_moved, txt) >= 0: return 1
|
||||
if t.typ != ST_PROPERTY: return 0
|
||||
line_start: int = int(a.doc.index.LineStart(t.sl))
|
||||
if sb <= 0 or a.doc.text[line_start + sizet(sb - 1)] != '.': return 0
|
||||
p: int = sb - 2
|
||||
while p >= 0:
|
||||
ch: char = a.doc.text[line_start + sizet(p)]
|
||||
if ch == ' ' or ch == '\t': p -= 1
|
||||
else: break
|
||||
e: int = p
|
||||
while p >= 0:
|
||||
if _IsIdentByte(a.doc.text[line_start + sizet(p)]) == 0: break
|
||||
p -= 1
|
||||
if e < 0 or e <= p: return 0
|
||||
base: str = LspSource.SliceBytes(pool, a.doc, t.sl, p + 1, t.sl, e + 1)
|
||||
if base is not None and LspChecks._NameListFind(_sem_moved, base) >= 0: return 1
|
||||
return 0
|
||||
|
||||
|
||||
def _AstStream(pool: memhub.MemManager*, a: LspSymbols.LspAnalysis*,
|
||||
ctx: LspSemCtx*) -> list[LspSemToken*]*:
|
||||
global _sem_moved_line, _sem_moved
|
||||
_sem_moved_line = -1
|
||||
_sem_moved = None
|
||||
out: list[LspSemToken*]* = list[LspSemToken*](pool, 64)
|
||||
syms: list[LspSymbols.LspSymbol*]* = a.symbols
|
||||
occs: list[LspSymbols.LspOccurrence*]* = a.occs
|
||||
@@ -362,16 +411,16 @@ def _AstStream(pool: memhub.MemManager*, a: LspSymbols.LspAnalysis*,
|
||||
if sym_t is None and occ_t is None:
|
||||
break
|
||||
if sym_t is None:
|
||||
out.append(occ_t)
|
||||
if _MovedDrop(pool, a, occ_t) == 0: out.append(occ_t)
|
||||
continue
|
||||
if occ_t is None:
|
||||
out.append(sym_t)
|
||||
if _MovedDrop(pool, a, sym_t) == 0: out.append(sym_t)
|
||||
continue
|
||||
if _Before(sym_t, occ_t) != 0:
|
||||
out.append(sym_t)
|
||||
if _MovedDrop(pool, a, sym_t) == 0: out.append(sym_t)
|
||||
oi -= 1
|
||||
else:
|
||||
out.append(occ_t)
|
||||
if _MovedDrop(pool, a, occ_t) == 0: out.append(occ_t)
|
||||
si -= 1
|
||||
return out
|
||||
|
||||
|
||||
Reference in new issue
Block a user