Skip to content

Qualified calls and api polish - #45

Merged
Kristof Roomp (mcroomp) merged 2 commits into
mainfrom
qualified-calls-and-api-polish
May 18, 2026
Merged

Kristof Roomp (mcroomp) merged 2 commits into
mainfrom
qualified-calls-and-api-polish

Conversation

@mcroomp

Copy link
Copy Markdown
Contributor

No description provided.

Kristof Roomp and others added 2 commits May 18, 2026 14:21
…lish

This branch bundles two related streams of work for tscodesearch:

QUALIFIED-CALL INDEXING & VAR-TYPE RESOLVER
- New ``qualified_calls`` Tantivy field stores ``Type.Method`` tokens for
  call sites: static-style receivers (``Foo.Save()`` → ``Foo.Save``) and
  resolved-receiver forms (``store.Save()`` where ``store: IRepo`` →
  ``IRepo.Save``). The receiver type is pinned by a new method-scoped
  var-type map (``_build_var_type_map``) with conflict suppression — names
  that map to multiple types in one scope emit no qualified form.
- Block-level scoping: ``block`` / ``catch_clause`` / ``for_statement`` /
  ``foreach_statement`` / ``using_statement`` are scope nodes, so sibling
  blocks (if/else, multiple catch arms, two for-loops) isolate their
  declarations. Fixes prior false negatives where shadowed names
  collapsed to ``None`` under method-wide flat scoping.
- Best-guess inference heuristics in ``_infer_var_type``: await unwrap,
  generic-method type-argument (``c.Resolve<IService>()`` → ``IService``),
  static-factory pattern (``Widget.Create()`` → ``Widget``), ternary
  branch try-each, member-access (instance ``obj.Prop`` → ``Prop`` /
  static ``Type.Member`` → ``Type``), and foreach-over-collection
  element-type extraction across scope boundaries (handles
  ``foreach (var x in someField)`` where ``someField`` is in file scope).
- ``calls`` mode now searches ``call_sites,qualified_calls,path_tokens``
  so bare ``Save`` and qualified ``IRepo.Save`` both hit. The AST
  post-filter in ``q_calls`` is upgraded to match by resolved receiver
  too — ``q_calls("IRepo.Save")`` finds ``store.Save()`` when ``store``
  resolves to ``IRepo``.
- New ``var_type NAME`` listing mode: for each identifier occurrence,
  report the resolved type (or ``(unresolved)`` / ``(conflicting)``).
  Saves an ``at LINE:COL`` round-trip when you just want the type.
- ``q_at`` fix: ``field_declaration`` and ``event_field_declaration``
  carry their name on a nested ``variable_declarator`` (no direct
  ``name`` field), so the position scope chain was silently dropping
  the field. Now extracted via ``_field_declarator_name``.
- ``q_calls`` anchors chained calls at the method-name token. The
  reported line and source text point at where the matched identifier
  actually appears, not the start of the outer multi-line invocation.
- Windows file-handle flake fix: ``Backend.upsert_many`` retries the
  whole add+commit cycle on transient Windows IO errors (Defender /
  mmap-release races on a freshly-created collection's first commit).
  ``tests.helpers._delete_collection`` adds a parent-directory canary
  on Windows so tearDownClass doesn't return until the next setUpClass
  can write into ``.tantivy/``.

API POLISH (Phases 0-5 from the improvement plan)
- Phase 0 (docs/errors): ``uses_kind`` default-union now documented;
  ``accesses_of`` docstring cross-links to ``all_refs`` for implicit-this
  reads; ``query_codebase`` redirect message expanded to cover file-only
  modes (``body``/``at``/``params``/``var_type``) — not just listing
  modes; CLAUDE.md notes the required ``mcp__tscodesearch__*`` prefix.
- Phase 1 (output trimming): replaced the box-drawing banner
  (``── [kind] name (lines X–Y) ──``) on ``body`` / ``declarations``
  output with a compact ASCII header (``[kind] name S-E:``) across all
  five language modules. Saves ~30 chars per match and avoids
  ``cp1252`` codec errors on Windows consoles.
- Phase 4a: tier-2/3 follow-up suggestions and the docstring examples
  drop the ``$SRC_ROOT/`` placeholder — the tool accepts the bare
  relative path that ``query_codebase`` itself returns.
- Phase 5 (visibility filter): captures explicit C# access modifiers
  plus language defaults (top-level types → internal, nested types →
  private, interface members → public, enum body members → public,
  class/struct/record members → private). Compound modifiers collapse to
  their dominant role (``protected internal`` → ``protected``,
  ``private protected`` → ``private``). Exposed as a comma-separated
  ``visibility`` argument on ``query_codebase`` and ``query_single_file``
  for the four declaration modes (declarations / classes / methods /
  fields). Two parallel Tantivy fields (``type_visibilities``,
  ``member_visibilities``) so a "files with at least one public member"
  query doesn't catch files whose only public thing is a top-level type.
- Diagnostic: new ``scripts/probe_resolved.py`` categorises lowercase-
  receiver gap candidates so future tuning targets the biggest patterns.

TESTS: +173 new cases (1099 total, all green; 10× full-suite stability
sweep clean). Coverage spans var-type resolution, block scoping, inference
heuristics, qualified-receiver matching, ``var_type`` mode, ``q_at`` field
scope, output format, redirect routing, Windows IO retry, and visibility
extraction + filtering.

DOCS: CLAUDE.md updated with the new ``qualified_calls`` schema field,
revised ``calls`` semantics, ``var_type`` mode entry, ``visibility``
filter section, and the MCP-prefix note.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Strip non-ASCII codepoints (em dashes, arrows, box drawing, ellipsis,
bullets, math symbols, check marks) from every .py / .md / .mjs / .js
file under the repo and replace each with its ASCII analogue:

  EM DASH (U+2014) / EN DASH (U+2013)      -> '--' or '-'
  RIGHTWARDS / LEFTWARDS ARROW             -> '->' / '<-'
  RIGHTWARDS DOUBLE ARROW (U+21D2)         -> '=>'
  HORIZONTAL ELLIPSIS (U+2026)             -> '...'
  BOX DRAWINGS LIGHT / DOUBLE HORIZONTAL   -> '-' / '='
  BOX DRAWINGS LIGHT VERTICAL              -> '|'
  BULLET (U+2022)                          -> '*'
  GREATER-/LESS-THAN OR EQUAL TO           -> '>=' / '<='
  ELEMENT OF (U+2208)                      -> ' in '
  MULTIPLICATION SIGN (U+00D7)             -> 'x'
  CHECK MARK / BALLOT X                    -> 'OK' / 'NO'

Touches 80 files and ~17k character positions. Mostly cosmetic
section-separator comments and prose dashes, but also includes the
``q_accesses_on`` output marker (``<-``) and a handful of f-strings
that the daemon and tools emit.

Adds CLAUDE.md "ASCII only" rule with the Unicode-name-keyed reference
table (so the rule's own text doesn't violate the rule). Adds two
helper scripts:

  scripts/find_nonascii.py     audits the tree and reports every
                               non-ASCII codepoint by file region
                               (docstring / string literal / comment /
                               code), separating hot-path modules
                               (query / indexserver / mcp_server /
                               tsquery_server) from cold.
  scripts/replace_nonascii.py  the mass-rewriter used for this commit;
                               dry-run by default, --apply to write.

All 1099 tests still pass; no test assertion depended on the old
Unicode forms.

Motivation: Windows console encoding (cp1252) and many downstream tools
misrender or fail on the previously-used codepoints, and the
``[method] name S-E:`` tool output had been triggering ``cp1252 codec
can't encode`` errors when piped to Python sub-processes.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Comment thread scripts/find_nonascii.py
by_cat: dict[str, list] = {}
in_docstring = False
tag = None
for ln, line in enumerate(open(path, encoding="utf-8").read().splitlines(), 1):

for path in _walk_targets():
try:
text = open(path, encoding="utf-8").read()
Comment thread scripts/find_nonascii.py
count = line.count(q)
if count % 2 == 1:
in_docstring = not in_docstring
tag = q if in_docstring else None
Comment thread scripts/find_nonascii.py
import os
import re
import sys
import unicodedata
Comment thread scripts/probe_resolved.py
Comment on lines +21 to +24
from query.cs import (
_build_var_type_map, _find_all, _text, _CsIndex, _DESCRIBE_NODE_TYPES,
_q_all_call_site_infos,
)
@mcroomp
Kristof Roomp (mcroomp) merged commit cf1ed81 into main May 18, 2026
7 checks passed
@mcroomp
Kristof Roomp (mcroomp) deleted the qualified-calls-and-api-polish branch September 24, 2026 07:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant