You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
FindLocation returns Location.None for any value the file writes with a JSON escape: C:\temp, say "hi", and System.Text.Json-written non-ASCII names like Ω·m² can't be located #68
MetadataFile.IndexOfToken (SourceGeneratorToolkit/MetadataFile.cs, around lines 139-143) searches the raw file text: first for "<value>", then for <value>. Both FindLocation(needle) and FindLocation(anchor, needle) go through it.
A generator normally passes a value it got back from Deserialize<T>, which is unescaped. The file holds the escaped JSON form, so for any such value neither search can match.
I ran this in a scratch test against the current main:
Call
Result
FindLocation(@"C:\temp")
Location.None
FindLocation("Café")
Location.None
FindLocation("say \"hi\"")
Location.None
FindLocation("Alpha", @"C:\temp")
Location.None
FindLocation("Alpha") (control)
(2,15)-(2,20), correct
Why it matters
JSON requires \ and " to be escaped. So no value containing a backslash or a quote can ever be located: Windows paths, regex patterns, format strings.
System.Text.Json's default encoder escapes all non-ASCII and + < > & '. Serializing "Ω·m²" gives "\u03A9\u00B7m\u00B2". Units and physics metadata, which are the main consumers, hit this directly.
When the anchor is the escaped value, the scoped overload falls back to the first unscoped match of the needle. The diagnostic then lands on the wrong entry, which is exactly what the scoped overload exists to prevent.
The README says FindLocation "maps a name from the metadata back to a position in the file".
Suggested fix
Match against decoded JSON string tokens rather than raw text:
Scan Text for string literals.
Unescape each one, compare it with the needle, and return the literal's span. The span should cover the literal's content between the quotes, as now.
Keep the raw search as the fallback for non-string tokens such as numbers.
This is distinct from #66 (needle key written before the anchor key), #33 and #63 (substring matches), and #28.
Acceptance criteria
FindLocation locates values whose file form contains \\, \", or \uXXXX escapes, for both upper- and lowercase hex, in both the unscoped and the scoped overloads.
The returned span covers the escaped literal in the file.
Tests cover a backslash path, an embedded quote, and a \u-escaped non-ASCII name.
Priority: Medium. Code generation itself is unaffected; only the diagnostic location is wrong. But it hits every value with a backslash or quote, and every non-ASCII name System.Text.Json writes. Units and physics metadata, the main consumers, hit it directly. In the scoped overload the diagnostic lands on the wrong entry rather than nowhere.
Suggested area:SourceGeneratorToolkit/MetadataFile.cs, in IndexOfToken. The maintainer should own it.
Next steps: Scan the string literals, unescape each one, compare it with the needle, and return the content span of the escaped literal. Keep the raw search as a fallback for non-string tokens. Add tests for a backslash path, an embedded quote, and \u escapes in both hex cases, across both overloads.
Activity
matt-edmondson commentedon Nov 6, 2026
Triage
System.Text.Jsonwrites. Units and physics metadata, the main consumers, hit it directly. In the scoped overload the diagnostic lands on the wrong entry rather than nowhere.SourceGeneratorToolkit/MetadataFile.cs, inIndexOfToken. The maintainer should own it.MetadataFile.FindLocation(anchor, needle)points the diagnostic at the wrong entry when the needle's key comes before the anchor's key in the same JSON object #66 (key order) and from MetadataFile.FindLocation(anchor, needle) points at the wrong entry when the anchor or needle is part of a longer name ("Meter" lands on "SquareMeter") #33 and Find a whole JSON string before a substring in FindLocation [patch] #63 (substring matches), as the issue notes.FindLocationpath forMetadataFile.FindLocation(anchor, needle)points the diagnostic at the wrong entry when the needle's key comes before the anchor's key in the same JSON object #66, but it doesn't address escapes. Expect a conflict inIndexOfToken, so land Point scoped FindLocation at the anchor's own entry when the needle is written first [patch] #67 first and build the decoded-token matching on top of it.Next steps: Scan the string literals, unescape each one, compare it with the needle, and return the content span of the escaped literal. Keep the raw search as a fallback for non-string tokens. Add tests for a backslash path, an embedded quote, and
\uescapes in both hex cases, across both overloads.Generated by Claude Code