Skip to content

Scoped FindLocation("Foot", "Meter") lands inside "SquareMeter" again when the exact "Meter" is before the anchor or in an earlier entry (#33 returns via #67's range split) #80

Open

Description

@matt-edmondson

What happens

These results come from running code against MetadataFile, using a console project that references the library at effd00a:

JSON FindLocation("Foot", "Meter") Expected
[{"name":"Foot","base":"Meter","alias":"SquareMeter"}] offset 24, "base":"Meter" ✅ same
[{"base":"Meter","name":"Foot","alias":"SquareMeter"}] offset 46, inside "SquareMeter" ❌ offset 9, "base":"Meter"
[{"name":"Meter"},{"name":"Foot","base":"Yard"},{"name":"SquareMeter"}] offset 63, inside "SquareMeter" ❌ the whole "Meter" at offset 10 (the documented fallback, "the first unscoped match")

When this happens, the diagnostic squiggle goes under the wrong name. In the second row it lands in the same entry. In the third row it lands in a different, correctly spelled entry. This is the symptom #33 fixed.

Why

IndexOfToken(value, start, end) (SourceGeneratorToolkit/MetadataFile.cs ≈ line 266) prefers an exact quoted match over a plain substring match, but only within the one range it is given. Since #67 (the fix for #66), FindLocation(anchor, needle) (≈ line 134) calls it on four ranges in turn:

  1. after the anchor, inside its object
  2. before the anchor, inside its object
  3. forward from the anchor
  4. the whole file, via FindLocation(needle)

Each call returns its range's substring hit as soon as that range has no exact hit. So a substring match in an earlier range beats an exact match in a later one:

  • Row 2: range 1 has no exact "Meter", so its substring match inside SquareMeter wins over the exact "Meter" in range 2.
  • Row 3: range 3 takes the substring match in the later entry, so the exact match that range 4 would find is never reached.

The two existing fixes each hold on their own, but the combination is untested. Open PR #76 (for #68) keeps the same per-range exact-then-substring shape, so it doesn't change this.

Suggested fix

Split IndexOfToken into an exact-only search and a substring-only search. In FindLocation(anchor, needle):

  • Run the exact-only search over all four ranges, in the current order.
  • Fall back to the substring search over the same ranges only when none of them has an exact match.

Acceptance criteria

Related: #33 and #66 (closed, the two fixes that combine here), #68 and PR #76 (escapes), #78 (comments).

Activity

  1. matt-edmondson commented on Nov 12, 2026

    @matt-edmondson
    ContributorAuthor

    Triage


    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions