Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ tests/CodeIndex.Tests/
- **Explicit graph-support hints** — `inspect`, MCP `analyze_symbol`, and direct MCP graph tools annotate unsupported language filters with graph-support metadata so AI clients can distinguish "unsupported language" from "supported but zero hits."
- **Hybrid symbol extraction** — Intentionally simple and dependency-light. Most languages still use compiled regex patterns, while JavaScript/TypeScript add a lightweight lexer/state machine for class-body method extraction, scope filtering, synthetic class-expression binding detection, and JS/TS-specific range resolution where regex alone is too brittle. HTML uses its own character-level tag-structure state machine instead of the generic pattern loop, because line-oriented regex cannot safely distinguish real `id="..."` attributes from attribute-lookalike strings inside quoted values, multi-line quoted values, `<script>`/`<style>`/`<textarea>`/`<title>` raw-text bodies, or `<!-- ... -->` comments. Accuracy is still secondary to speed and portability, but the index stores richer symbol metadata such as definition ranges, optional body ranges, signatures, enclosing symbols, qualified container paths, authoritative family keys, visibility, and return types when the regex patterns or JS/TS/HTML state machine can infer them. Visual Basic container extraction also uses case-insensitive `VisualBasicEnd` range tracking so partial families keep stable body ranges and family metadata across files.
- **Authoritative hotspot-family trust** — `hotspots` only promotes duplicate-name families back to codebase-wide counts when persisted `symbols.container_qualified_name` / `symbols.family_key` were produced under the current per-language `hotspot_family_version_*` contract. Readiness stamps and marker fingerprints live in `codeindex_meta`, so legacy, mixed, or partial-refresh DBs degrade explicitly instead of silently reusing stale cross-file family identities.
- **Authoritative C# metadata-target trust** — `deps` / `impact` metadata-attribute edges use persisted `symbols.is_metadata_target` when the index was produced under the current `metadata_target_version_csharp` contract stored in `codeindex_meta`, instead of the old `signature LIKE '%: %'` heuristic that could not distinguish `class FooAttribute : Attribute` from an impostor `class FooAttribute : BaseService`. The resolver walks the C# class base list with fixed-point transitive resolution through same-DB class rows, scope-aware through the deriving class's namespace/nesting chain, and import-aware through the deriving file's `using Namespace;` / `using Alias = FQN;` directives plus `global using` aggregated across the repo. For unqualified base names the scope chain and then the per-file import map are consulted before any global simple-name bucket; for qualified bases (containing `.` or `::`) the fully-qualified index is used directly, and the first segment is also expanded against `using Alias = Target;` entries — splitting on whichever of `.` (member access) or `::` (qualified-alias-member, §7.8) appears first — so both `class FooAttribute : Alias.MetaBase` and `class FooAttribute : Alias::MetaBase` resolve to `Target.MetaBase` before the qualified-index lookup (an alias whose target is `System` or `System.Attribute` re-triggers the direct-Attribute rule after expansion). C# verbatim identifiers (`@Foo.@Bar`, `class X : @BaseAttr`, `global::@Foo.@Bar.BaseAttr`) are canonicalized to their non-verbatim form on both the writer side (import map, qualified keys, symbol names, base list) and the reader side so `@class` ≡ `class` matches identity without divergent lookup keys. Only truly unresolved external bases fall through to the BCL `Attribute`-suffix convention. Reader uses a three-way branch: (1) readiness-stamped → `is_metadata_target = 1`; (2) column present but row not stamped (legacy) → `signature LIKE '%: %'`; (3) column missing on read-only legacy DB → name-suffix fallback. `codeindex_meta.metadata_target_version_csharp` tracks the contract (bumped 1→2 for iter-5 import-awareness, 2→3 for iter-6 writer-side verbatim `@` normalization, 3→4 for iter-7 verbatim-identifier declaration acceptance + `::` boundary normalization, 4→5 for iter-8 alias-qualified base expansion, 5→6 for iter-9 `::` alias separator in qualified-base expansion); older stamps force the reader to degrade to the legacy heuristic until a reindex republishes `is_metadata_target`. `status --json` exposes this via `csharp_metadata_target_ready` (#435).
- **Granular symbol kinds** — Symbols use semantically precise kinds: `function`, `class`, `struct`, `interface`, `enum`, `property`, `event`, `delegate`, `namespace`, `import`. Languages map their constructs to the closest kind (e.g. Rust `trait` → `interface`, Swift `protocol` → `interface`, PHP `trait` → `interface`). Symbol search and definition results are ranked by visibility (public first).
- **DB index optimization** — SQLite indexes are actively maintained to match query patterns. When adding new query features (new commands, new ORDER BY clauses, new JOIN patterns), always evaluate whether a dedicated index would improve performance. Use `CREATE INDEX IF NOT EXISTS` for safe additive changes.
- **Human-readable default** — All commands default to human-readable output. Use `--json` for machine-readable JSON lines (AI-friendly).
Expand Down Expand Up @@ -378,6 +379,7 @@ tests/CodeIndex.Tests/
- **graph 対応ヒントの明示** — `inspect`、MCP の `analyze_symbol`、直接の MCP graph ツールは、未対応言語フィルタに graph 対応メタデータを付けて返し、AI クライアントが「未対応言語」と「対応言語だが 0 件」を区別できるようにする。
- **ハイブリッドなシンボル抽出** — 意図的にシンプルかつ依存を増やさない方針。大半の言語はコンパイル済み正規表現で処理し、JavaScript / TypeScript だけは class body の method 抽出、scope filtering、synthetic class expression の binding 判定、JS/TS 固有の range 解決で正規表現だけでは脆い箇所を軽量 lexer / state machine で補う。HTML は行単位の正規表現では引用符付き値内、複数行の引用符付き値、`<script>` / `<style>` / `<textarea>` / `<title>` の raw-text 本体、`<!-- ... -->` コメントに含まれる属性名に似た文字列を本物の `id="..."` 属性から確実に区別できないため、専用の文字単位タグ構造 state machine に置き換えている。引き続き速度とポータビリティを精度より優先しつつ、正規表現パターンや JS/TS/HTML state machine から推論できる範囲で定義範囲、本体範囲、シグネチャ、親シンボル、修飾付きコンテナ経路、正式なグループキー、可視性、戻り値型もインデックスに保持する。Visual Basic のコンテナ抽出も大文字小文字非依存の `VisualBasicEnd` 範囲追跡を使うため、partial 型ファミリーでもファイルをまたいで安定した本体範囲と `hotspots` 用グループメタデータを維持できる。
- **`hotspots` の正式な family trust** — `hotspots` が重名グループをコードベース全体の件数へ昇格させるのは、永続化済み `symbols.container_qualified_name` / `symbols.family_key` が現行の言語別 `hotspot_family_version_*` 契約で生成されたときだけ。readiness stamp と marker fingerprint は `codeindex_meta` に置き、旧形式・混在・部分更新直後の DB は古いファイル横断グループ識別子を黙って再利用せず、明示的に縮退する。
- **C# metadata-target の正式な trust** — `deps` / `impact` の metadata attribute edge は、現行の `metadata_target_version_csharp` 契約(`codeindex_meta` に保存)で作られた `symbols.is_metadata_target` が存在するときは、旧来の `signature LIKE '%: %'` ヒューリスティックではなくその永続化値を使う。ヒューリスティックは `class FooAttribute : Attribute` と impostor の `class FooAttribute : BaseService` を区別できず、AI フローで metadata edge が黙って消える原因になっていた。resolver は C# クラスの base list を同 DB 内の class 行で fixed-point に展開して解決し、deriving class の名前空間 / nest チェーン(scope-aware)と、deriving file の `using Namespace;` / `using Alias = FQN;` ディレクティブ・リポジトリ全体集約の `global using`(import-aware)も考慮する。非修飾な base 名はスコープ → per-file import map の順に引いた後でのみ global simple-name bucket を使い、`.` または `::` を含む修飾 base は fully-qualified 索引で直接引きつつ、先頭セグメントを `using Alias = Target;` で展開する。区切りは `.`(メンバ アクセス)と `::`(qualified-alias-member、§7.8)のうち先に現れた方で分割するため、`class FooAttribute : Alias.MetaBase` と `class FooAttribute : Alias::MetaBase` のどちらも qualified 索引引き前に `Target.MetaBase` に書き換える(alias 先が `System` や `System.Attribute` の場合は展開後に直接 Attribute ルールを再適用する)。C# verbatim 識別子(`@Foo.@Bar` / `class X : @BaseAttr` / `global::@Foo.@Bar.BaseAttr`)は書き込み側(import map・qualified キー・symbol 名・base リスト)でも読み取り側でも canonical 形に正規化され、`@class` ≡ `class` の同一性が分岐キーで崩れないようにする。未解決の外部基底のみ BCL 規約(`Attribute` サフィックス)へフォールバックする。reader は (1) readiness あり → `is_metadata_target = 1`、(2) 列はあるが stamp 未完(legacy 行)→ `signature LIKE '%: %'`、(3) 列すらない読み取り専用 legacy DB → 命名のみ、の 3 way 分岐で縮退する。`codeindex_meta.metadata_target_version_csharp` が契約を追跡し、iter-5 の import-aware 化で 1→2、iter-6 の書き込み側 verbatim `@` 正規化で 2→3、iter-7 の verbatim 識別子宣言受理+`::` 境界正規化で 3→4、iter-8 の alias 修飾基底展開で 4→5、iter-9 の qualified 基底展開における `::` alias 区切り対応で 5→6 に上げている。古い stamp は reader を legacy ヒューリスティックへ縮退させ、再 index で republish されるまで誤判定を防ぐ。`status --json` では `csharp_metadata_target_ready` として公開する(#435)。
- **詳細なシンボル種別** — シンボルは意味的に正確な種別を使用: `function`、`class`、`struct`、`interface`、`enum`、`property`、`event`、`delegate`、`namespace`、`import`。各言語は最も近い種別にマッピングする(例: Rust の `trait` → `interface`、Swift の `protocol` → `interface`、PHP の `trait` → `interface`)。シンボル検索と定義の結果は可視性でランキングされる(public が最優先)。
- **DBインデックス最適化** — SQLite インデックスはクエリパターンに合わせて積極的に維持管理する。新しいクエリ機能(新コマンド、新 ORDER BY、新 JOIN パターン)を追加するときは、専用インデックスで性能改善できるかを常に評価する。安全な追加のため `CREATE INDEX IF NOT EXISTS` を使用する。
- **人間向けがデフォルト** — 全コマンドのデフォルト出力は人間向け。`--json`でAI向けJSONライン出力に切り替え。
Expand Down
Loading
Loading