Hacktoberfest 2026:メンテナが10月に向けて印を付けた、オープンで初心者向けの issue。 Hacktoberfest の issue を見る

AnnotationList.FindDepthFirst misses descendants in tied containers depending on insertion order

オープン
#554 コメント 0 件 リアクション 0 件 担当者 0 名 GitHub で見る

メンテナーはふだん 1 日以内に返信

@johnml1135 がすでに取り組んでいます。

2026年10月23日 から。

  • #556 @johnml1135 による — オープン

評価

難易度
4/5
見積もり時間
3〜5日
初心者へのやさしさ
56/100
issue の種類
バグ
明瞭さ
明確に書かれている
活発さ
活発
技術スタック
csharp
領域
backend

調査の方向性

Start with src/SIL.Machine/Annotations/AnnotationList.cs::FindDepthFirst and the minimal reproduction in the issue. Add deterministic tests for tied and nested containers in both insertion orders and search directions; verify the expected descendant is found without returning an unrelated annotation. Keep the change separate from #506.

索引モデルが issue の本文から書いたものです。

説明

AnnotationList.FindDepthFirst can miss a segment inside equal-range sibling containers solely because their insertion order changes. This is separate from #506's skip-list boundary defect.

Reproduced against Machine 259920414132bdd5a85542722d9af5509aed8943 and again with the proposed first-match-in-search-direction fix applied locally. The latter fixes range traversal but leaves this case unchanged. This report concerns the shared annotation API; no HermitCrab grammar reaching the case has been demonstrated.

Two sibling annotations both cover [n0,n2]; only one owns the three segment annotations. Looking up n1 should return its annotation regardless of which sibling was inserted first. Current results:

ownerAddedFirst=True; found=False; foundSegment=False
ownerAddedFirst=False; found=True; foundSegment=True

The non-found path in src/SIL.Machine/Annotations/AnnotationList.cs::FindDepthFirst descends only into the single candidate returned by Find; it does not search another equal-range container when that candidate cannot supply the descendant. A deterministic layout alone cannot resolve this ownership choice.

Minimal console reproduction (reference src/SIL.Machine/SIL.Machine.csproj; reflection sets only the test instance RNG, with no production hook):

using System.Reflection;
using SIL.Machine.Annotations;
using SIL.Machine.DataStructures;
using SIL.Machine.FeatureModel;

foreach (bool ownerAddedFirst in new[] { true, false })
{
    var annotations = new AnnotationList<ShapeNode>();
    typeof(BidirList<Annotation<ShapeNode>>)
        .GetField("_rand", BindingFlags.Instance | BindingFlags.NonPublic)!
        .SetValue(annotations, new Random(0));
    var shape = new Shape(begin => new ShapeNode(FeatureStruct.New().Value), annotations);
    ShapeNode n0 = shape.Add(FeatureStruct.New().Value);
    ShapeNode n1 = shape.Add(FeatureStruct.New().Value);
    ShapeNode n2 = shape.Add(FeatureStruct.New().Value);
    var owner = new Annotation<ShapeNode>(Range<ShapeNode>.Create(n0, n2), FeatureStruct.New().Value);
    owner.Children.AddRange(new[] { n0.Annotation, n1.Annotation, n2.Annotation });
    var empty = new Annotation<ShapeNode>(Range<ShapeNode>.Create(n0, n2), FeatureStruct.New().Value);
    if (ownerAddedFirst)
    {
        shape.Annotations.Add(owner, false);
        shape.Annotations.Add(empty, false);
    }
    else
    {
        shape.Annotations.Add(empty, false);
        shape.Annotations.Add(owner, false);
    }

    bool found = shape.Annotations.FindDepthFirst(n1, out Annotation<ShapeNode> result);
    Console.WriteLine($"ownerAddedFirst={ownerAddedFirst}; found={found}; foundSegment={ReferenceEquals(result, n1.Annotation)}");
}

Acceptance criteria:

  • Find the descendant in both insertion orders and both search directions, with deterministic coverage of tied containers and nested containers.
  • Preserve existing direction and boundary semantics, and verify that no unrelated annotation is returned.
  • Keep the fix separately reviewable from #506. Do not claim a parser-level reproduction without one.

Related: #506, #500. The reproduction was rerun directly during the 2026-10-23 investigation; the first-match boundary fix does not solve this case.

主要言語
C#
スター
29
フォーク
16
平均マージ
10日 4時間
マージ済み PR(30日)
13

環境構築

  • Dockerfile・Docker Compose ファイルなし
  • プルリクエストのテンプレートあり
  • コントリビューションガイドなし

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

sillsdev/machine のほかの issue

sillsdev/machine の issue をすべて見る

似ている issue

C# の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。