diff --git a/App/lib/lsp/LspSymbols.vp b/App/lib/lsp/LspSymbols.vp index e483961..0042fbe 100644 --- a/App/lib/lsp/LspSymbols.vp +++ b/App/lib/lsp/LspSymbols.vp @@ -901,7 +901,13 @@ def _DeclImportOcc(pool: memhub.MemManager*, a: LspAnalysis*, scope: LspScope*, line0: int = alias.lineno - 1 if line0 < 0: return - col: int = _FindWordInLine(a.doc, line0, alias.col_offset, bound) + start_col: int = alias.col_offset + # `import a.b.c as c` / `from x import c as c`: the alias can repeat a name that already + # appears in the source path, so start after the imported name to land on the `as` alias. + if alias.asname is not None and alias.name is not None: + if string.strlen(alias.asname) > 0: + start_col = alias.col_offset + int(string.strlen(alias.name)) + col: int = _FindWordInLine(a.doc, line0, start_col, bound) if col < 0: return o: LspOccurrence* = _AddOcc(pool, a, scope, bound, alias.lineno, col, diff --git a/Tools/lsp/fixtures/gate10_use.vp b/Tools/lsp/fixtures/gate10_use.vp index afa05ac..8fae020 100644 --- a/Tools/lsp/fixtures/gate10_use.vp +++ b/Tools/lsp/fixtures/gate10_use.vp @@ -6,6 +6,7 @@ from .gate10_extra import * import gate10_types import gate10_pkg.sub.mod import gate10_pkg.sub as pkgsub +import gate10_pkg.sub as sub import ghost_lib.path diff --git a/Tools/lsp/probe.py b/Tools/lsp/probe.py index 1ccbc43..86ec566 100644 --- a/Tools/lsp/probe.py +++ b/Tools/lsp/probe.py @@ -1562,6 +1562,24 @@ def gate10(exe: str) -> int: if not alias_def[0]["uri"].replace("\\", "/").endswith("gate10_pkg/sub/__init__.vp"): raise AssertionError(f"aliased dotted import target is wrong: {alias_def}") + # Alias repeating the last path segment must still be a separate occurrence at the `as` end. + same_line = _position(text, "import gate10_pkg.sub as sub") + for delta, segment in ((7, "gate10_pkg"), (18, "sub"), (25, "sub")): + pos = {"line": same_line["line"], "character": same_line["character"] + delta} + if not _find_token(sem_tokens, pos["line"], pos["character"], + sem_types.index("namespace")): + raise AssertionError(f"repeated alias import is not highlighted: {segment} {pos}") + same_alias = {"line": same_line["line"], "character": same_line["character"] + 25} + same_def = client.request( + "textDocument/definition", + {"textDocument": {"uri": uri}, "position": same_alias}, + timeout=120.0, + ).get("result") + if not isinstance(same_def, list) or not same_def: + raise AssertionError(f"repeated alias definition failed: {same_def}") + if not same_def[0]["uri"].replace("\\", "/").endswith("gate10_pkg/sub/__init__.vp"): + raise AssertionError(f"repeated alias target is wrong: {same_def}") + ghost_line = _position(text, "import ghost_lib.path") for delta, segment in ((7, "ghost_lib"), (17, "path")): pos = {"line": ghost_line["line"], "character": ghost_line["character"] + delta}