Skip to content

refactor: simplify IsLatinLetter range test, document broad catch - #461

Merged
twcclegg merged 2 commits into
mainfrom
refactor/codeql-code-quality
Sep 5, 2026
Merged

refactor: simplify IsLatinLetter range test, document broad catch#461
twcclegg merged 2 commits into
mainfrom
refactor/codeql-code-quality

Conversation

@twcclegg

@twcclegg twcclegg commented Sep 5, 2026

Copy link
Copy Markdown
Owner

The four note-severity maintainability alerts. Two produced changes; two are deliberately declined, because a note-level style hint is not worth making the code worse.

Fixed

cs/complex-condition - PhoneNumberMatcher.cs:221. IsLatinLetter's six chained letter >= x && letter <= y clauses joined by || became a single relational pattern — return letter is <= BASIC_LATIN or (>= ... and <= ...) or ... — one arm per Unicode block, using '\uXXXX' char literals.

All operands are pure comparisons on a char, so short-circuit order is irrelevant to behavior, and and binds tighter than or exactly as && binds tighter than || - the original grouping is preserved. Ranges, their order, and the Unicode block comments are unchanged. Char literals replaced the hex ints because relational patterns require a constant of the matched type; that form already appears elsewhere in this file. Pattern combinators are already used elsewhere in the library (PrefixFileReader.MayFallBackToEnglish).

cs/catch-of-all-exceptions - PhoneNumbers.MetadataBuilder/Program.cs:60. Kept, now documented. This is the process-wide handler in Main for a build-time tool, and it was never a silent swallow: it writes ex.Message and the full exception to stderr and returns exit code 1, failing the invoking MSBuild target. The guarded work spans XML parsing, file I/O, GZipStream and named-mutex operations, so a narrowed catch list would be a long guess that converts anything unanticipated into an unhandled-exception crash dump instead of a readable one-line diagnostic - with no change to whether the build fails. A comment now states that. The alert stays open; no query-filters exclusion was added for it.

Declined

cs/missed-ternary-operator - PhoneNumberUtil.cs:1336. The if is guarded by a ~17-line condition that is almost entirely comment text explaining the MX/CL/UZ and non-geo dialling rules. The branches are one line each, so a ternary would strand the ?/: arms far below the formattedNumber = target at the bottom of a comment block that is the whole point of the construct. The if/else is clearer.

cs/linq/missed-select - PrefixFileReader.cs:66. The loop body is not a projection: it filters malformed resource names (two continues), parses a country calling code, and mutates a SortedDictionary. Only its first line maps the iteration variable. This is a startup path - LoadFileNamesFromManifestResources is called from the PrefixFileReader constructor, which backs PhoneNumberOfflineGeocoder / PhoneNumberToCarrierMapper / PhoneNumberToTimeZonesMapper construction - and AGENTS.md documents cold-start and allocation cost as tracked here. Appending .Select to the existing .Where would add a delegate plus another enumerator allocation on that path for zero readability gain.

Verification

  • dotnet build csharp/PhoneNumbers.slnx -p:TargetFrameworks=net10.0 - 0 warnings, 0 errors.
  • PhoneNumbers.csproj also built across all TFMs (netstandard2.0 + net8.0 + net10.0) to confirm the pattern syntax compiles on the netstandard2.0 leg.
  • dotnet test csharp/PhoneNumbers.slnx -p:TargetFrameworks=net10.0 - 491 passed, 0 failed, 0 skipped.
  • Targeted TestPhoneNumberMatcher run - 43 passed, including TestIsLatinLetter, which covers Latin, accented, combining-mark, CJK, kana, digit and punctuation inputs.

Two of the four note-severity CodeQL maintainability alerts in this group
were worth acting on; the other two were not, and are left alone
deliberately.

PhoneNumberMatcher.IsLatinLetter (cs/complex-condition) rewrites the
block membership test as a single relational pattern instead of six
chained `>= x && <= y` comparisons joined by `||`. The ranges, their
order and the Unicode block comments are unchanged, so the result is
identical for every char; the pattern form just states "letter is in one
of these ranges" directly. Character literals replace the hex ints
because a relational pattern needs a constant of the matched type, and
the escaped form matches the char literals already used in this file.

PhoneNumbers.MetadataBuilder.Main (cs/catch-of-all-exceptions) keeps its
broad catch and gains a comment explaining why. It is the process-wide
handler for a build-time tool over XML parsing, file I/O and named-mutex
code, and it already writes the full exception to stderr and returns a
non-zero exit code, so the build fails loudly. Narrowing it would only
swap a readable diagnostic for an unhandled-exception crash dump.

Deliberately not changed:

- PhoneNumberUtil.cs (cs/missed-ternary-operator): the if/else there is
  guarded by a seventeen-line commented condition explaining the MX, CL
  and UZ formatting rules. Folding it into a ternary would strand the
  `?` and `:` arms far below the assignment target and make a block that
  exists mostly to carry that explanation harder to read.

- PrefixFileReader.cs (cs/linq/missed-select): the loop body is not a
  projection. It filters malformed resource names, parses a country
  code, and mutates a dictionary; only its first line maps the iteration
  variable. Adding a `.Select` to the existing `.Where` would relocate
  that one line while adding a delegate and enumerator allocation on the
  geocoder/carrier/timezone construction path, which is startup cost
  this repo tracks.
@codecov

codecov Bot commented Sep 5, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 87.54%. Comparing base (8ad7fa2) to head (630e596).

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #461      +/-   ##
==========================================
+ Coverage   87.51%   87.54%   +0.02%     
==========================================
  Files          43       43              
  Lines        3886     3885       -1     
  Branches      991      991              
==========================================
  Hits         3401     3401              
  Misses        280      280              
+ Partials      205      204       -1     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

TestIsLatinLetter asserted only Basic Latin, Latin-1 Supplement and a
combining mark, so three arms of the range test - Latin Extended-A,
Extended-B and Extended Additional - had no assertion reaching them. That
showed up as a patch-coverage drop when the chained comparisons became a
relational pattern, since the untested arms are now visible as their own
branches.

Add one letter from each missing block. This is coverage the test should
always have had; the ranges themselves are unchanged.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant