Skip to content

feat(symbols): index private symbols in every language - #124

Closed
justinjdev wants to merge 1 commit into
feat/private-symbols-conventionsfrom
feat/private-symbols-all-languages
Closed

justinjdev wants to merge 1 commit into
feat/private-symbols-conventionsfrom
feat/private-symbols-all-languages

Conversation

@justinjdev

Copy link
Copy Markdown
Owner

Draft, stacked on #123. Review #123 first; this PR's diff is against that branch. It stays a draft until we've checked index size on a real TypeScript/JavaScript repo.

Summary

This converts every remaining language from the legacy is_visible filter to the visibility hook from #123, and removes is_visible. Private symbols are then indexed and tagged in every language. All of them respect symbols.include_private through the single drop point.

Per language

  • Rust:
    • pub → public; pub(crate)/pub(super)/pub(in …) → internal; no modifier or pub(self) → private.
    • Trait-impl methods (fmt, parse, …) are public. They used to be dropped.
  • C: static → private.
  • C++: class members follow public:/protected:/private: labels, defaulting to private in a class and public in a struct. A non-member static → private.
  • Java: modifiers as written, and package-private → internal. Members are narrowed by their enclosing types.
  • C#: the language's defaults apply: class members are private, interface members public, and top-level types internal. This fixes interface methods with no modifier, which used to be dropped.
  • Kotlin, Scala, Swift, PHP: modifiers as written, narrowed by enclosing types. Scala private[pkg] → internal; Swift fileprivate → private.
  • Gleam, Zig, Nim: anything not exported → private. Zig consts inside function bodies are no longer captured as symbols.
  • Clojure: defn- and ^:private → private. This also fixes ^:private leaking into the symbol name.
  • Elixir: defp, defmacrop, defguardp and @typep → private.
  • Ruby: methods in private/protected sections, and private def …. private :name is not tracked.
  • Lua: local function → private.
  • TS/JS:
    • The queries now also capture module-level unexported declarations and #private methods.
    • Names exported through a later export { … } count as public.
    • CommonJS module.exports is not recognised, so that code shows as private.
  • Unchanged (everything stays public): Haskell, OCaml, Erlang and Julia (their export lists are not read), Odin, R, Bash, SQL, YAML, TOML, HCL, COBOL.

EXTRACTOR_VERSION goes to 2, so an index built with #123 re-extracts once.

Behaviour changes with include_private = false, compared with main

  • Now kept where main dropped them:
    • Java package-private members
    • C# internal members, and interface members with no modifier
    • Kotlin internal, and Scala private[pkg]
    • Rust trait-impl methods
    • TS protected methods, and names exported through export { … }
  • Now dropped where main kept them:
    • Rust pub(self)
    • C++ private and static members
    • Ruby private sections, Lua locals, and Clojure ^:private

Size

This repo (Rust) indexes about 3.4x as many symbols with the default as with include_private = false: 1,207 vs 357 on current main. Before marking this ready: index a real TS/JS application repo and check the symbol count, DB size and search quality.

Test plan

  • Visibility per language: Python, Go, Rust, TS, JS, Java, C#, C/C++, Kotlin, Swift, Scala, Zig, Elixir, Perl, Lua, Ruby, Clojure, Dart, Gleam and Nim.
  • Existing tests: 34 tests that asserted private symbols were absent now assert they are present and tagged.
  • Checks: cargo test --all-features passes (1035 lib, 66 integration, 16 bin, 11 autoresearch). Clippy with -D warnings and cargo fmt --check are clean.
  • Index size and search quality on a real TS/JS repo.

🤖 Generated with Claude Code

https://claude.ai/code/session_01RdiKZaeLuAT6nGhrSLyMvA

Convert the remaining languages from the legacy `is_visible` filter to
the `visibility` hook and remove `is_visible`. Private symbols are now
indexed and tagged everywhere, and all of them honour
`symbols.include_private` through the generic drop.

- Rust pub/pub(crate)/pub(self) (trait-impl methods are public);
  C/C++ static and access labels; Java/C#/Kotlin/Swift/Scala/PHP
  modifiers, narrowed by enclosing types (Java package-private and
  C# defaults become internal); Gleam/Zig/Nim export markers;
  Clojure defn-/^:private; Elixir defp/defmacrop/defguardp/@TypeP;
  Ruby private/protected sections; Lua locals.
- TS/JS queries also capture module-level unexported declarations and
  `#private` methods. Names exported through `export { ... }` count as
  public.
- `is_definition` keeps the non-privacy filters: Clojure/Elixir generic
  call patterns and Zig locals.
- Bump EXTRACTOR_VERSION to 2 so indexes built on the previous commit
  re-extract once.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RdiKZaeLuAT6nGhrSLyMvA
@github-actions github-actions Bot added the enhancement New feature or request label Oct 3, 2026
@justinjdev
justinjdev deleted the branch feat/private-symbols-conventions October 3, 2026 22:14
@justinjdev justinjdev closed this Oct 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants