From 4e3331d442e3a5ae2c42ca9e36dd4861e6604742 Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Tue, 27 Oct 2026 17:34:59 +0800 Subject: [PATCH] =?UTF-8?q?fix(lsp):=20else/finally=20=E8=AF=AD=E5=8F=A5?= =?UTF-8?q?=E4=BD=93=E6=8C=89=E8=AF=AD=E5=8F=A5=E9=81=8D=E5=8E=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If/For/While 的 orelse 和 Try 的 finalbody 是语句列表,却用 _WalkExpr 遍历,else 里的调用基址/属性/名字没有 occurrence,只剩字符串高亮。改用 _WalkBody;gate10 增加多行 else 与单行 else 的跨模块 token/跳转断言。 --- App/lib/lsp/LspSymbols.vp | 10 +++++----- Tools/lsp/fixtures/gate10_use.vp | 12 ++++++++++++ Tools/lsp/probe.py | 15 +++++++++++++++ 3 files changed, 32 insertions(+), 5 deletions(-) diff --git a/App/lib/lsp/LspSymbols.vp b/App/lib/lsp/LspSymbols.vp index 0042fbe..eb94845 100644 --- a/App/lib/lsp/LspSymbols.vp +++ b/App/lib/lsp/LspSymbols.vp @@ -1156,19 +1156,19 @@ def _WalkStmt(pool: memhub.MemManager*, a: LspAnalysis*, scope: LspScope*, _WalkExpr(pool, a, scope, fr.target) _WalkExpr(pool, a, scope, fr.iter) _WalkBody(pool, a, scope, node.children) - _WalkList(pool, a, scope, fr.orelse) + _WalkBody(pool, a, scope, fr.orelse) return if k == ast.ASTKind.While: wh: ast.While* = (ast.While*)(node) _WalkExpr(pool, a, scope, wh.test) _WalkBody(pool, a, scope, node.children) - _WalkList(pool, a, scope, wh.orelse) + _WalkBody(pool, a, scope, wh.orelse) return if k == ast.ASTKind.If: iff: ast.If* = (ast.If*)(node) _WalkExpr(pool, a, scope, iff.test) _WalkBody(pool, a, scope, node.children) - _WalkList(pool, a, scope, iff.orelse) + _WalkBody(pool, a, scope, iff.orelse) return if k == ast.ASTKind.With: wi: ast.With* = (ast.With*)(node) @@ -1195,8 +1195,8 @@ def _WalkStmt(pool: memhub.MemManager*, a: LspAnalysis*, scope: LspScope*, _WalkExpr(pool, a, scope, h.type) _WalkBody(pool, a, scope, h.children) i += 1 - _WalkList(pool, a, scope, tr.orelse) - _WalkList(pool, a, scope, tr.finalbody) + _WalkBody(pool, a, scope, tr.orelse) + _WalkBody(pool, a, scope, tr.finalbody) return if k == ast.ASTKind.Match: mt: ast.Match* = (ast.Match*)(node) diff --git a/Tools/lsp/fixtures/gate10_use.vp b/Tools/lsp/fixtures/gate10_use.vp index 8fae020..f3efb24 100644 --- a/Tools/lsp/fixtures/gate10_use.vp +++ b/Tools/lsp/fixtures/gate10_use.vp @@ -37,3 +37,15 @@ def stub_use(t: StubThing) -> int: def stub_chain() -> int: return StubThing.count + + +def else_block(flag: int) -> int: + if flag != 0: + return 1 + else: + return extra_fn(EXTRA_CONST + 1) + + +def else_inline(flag: int) -> int: + if flag != 0: return 1 + else: return extra_fn(EXTRA_CONST + 2) diff --git a/Tools/lsp/probe.py b/Tools/lsp/probe.py index 5b60f70..dce8b2a 100644 --- a/Tools/lsp/probe.py +++ b/Tools/lsp/probe.py @@ -1507,6 +1507,21 @@ def gate10(exe: str) -> int: pos["character"] += delta if not _find_token(sem_tokens, pos["line"], pos["character"], sem_types.index(token_name)): raise AssertionError(f"missing cross-module semantic token for {label}: {pos}") + for needle, label in (("return extra_fn(EXTRA_CONST + 1)", "else block"), + ("return extra_fn(EXTRA_CONST + 2)", "inline else")): + pos = _position(text, needle) + pos["character"] += 7 + if not _find_token(sem_tokens, pos["line"], pos["character"], sem_types.index("function")): + raise AssertionError(f"missing cross-module token in {label}: {pos}") + else_def = client.request( + "textDocument/definition", + {"textDocument": {"uri": uri}, "position": pos}, + timeout=120.0, + ).get("result") + if not isinstance(else_def, list) or not else_def: + raise AssertionError(f"missing definition in {label}: {else_def}") + if not else_def[0]["uri"].replace("\\", "/").endswith("gate10_extra.vp"): + raise AssertionError(f"wrong definition in {label}: {else_def}") const_pos = _position(text, "EXTRA_CONST") if not _find_token_mods(sem_tokens, const_pos["line"], const_pos["character"], sem_types.index("variable"),