Summary
mur loc extract converts a C# ternary used for pluralization into an ICU select keyed on an English boolean. The result renders correctly in English but cannot be translated into any language whose plural rules differ from English — which defeats the purpose of the tool.
Repro
samples/TodoApp/Program.cs:254:
Caption($"{remaining} item{(remaining == 1 ? "" : "s")} left")
mur loc extract --source samples/TodoApp --output <out>
Extracted:
<data name="ItemFalseLeft" xml:space="preserve">
<value>{remaining} item{arg1, select, true {} false {s}} left</value>
<comment>auto-extracted from interpolation</comment>
</data>
Why this is wrong
The message is valid — I verified it against the real runtime engine (Jeffijoe.MessageFormat 8.0.0, the ICU engine per spec 005 §11.1) and it formats fine in English:
|
n=1 |
n=3 |
n=5 |
what mur generated |
1 item left |
3 items left |
5 items left |
The defect is structural. The one vs not-one decision was baked into C# at extract time, and the only branches exposed to a translator are true and false. Polish needs three plural forms; there is no branch to write the third in:
|
n=1 |
n=3 |
n=5 |
correct ICU plural (pl-PL) |
1 element |
3 elementy |
5 elementów |
the shape mur produced |
(no way to express this) |
|
|
The correct extraction is a plural, not a select:
{remaining, plural, one {# item} other {# items}} left
plural delegates the category choice to CLDR at format time, so a translator can add few/many. select on a boolean freezes English grammar into the resource.
Related problems in the same output
- Key name.
ItemFalseLeft is derived from message content including the literal false from the ternary.
- Placeholder name.
arg1 is opaque to a translator. 27 of 561 values extracted from samples/ReactorGallery carry arg{n}-style placeholders.
- No warning fired. Spec 005 §10.4 says the CLI "adds a comment hint (
consider adding plural support) when it detects a variable named count, total, num*, or similar quantity-suggesting names." remaining isn't in that list, so nothing warned — the broken message was emitted silently.
mur loc validate passes it. Its stated job is "Check ICU syntax and parameter consistency"; the message is syntactically valid, so it reports Validation passed: no errors or warnings. Nothing in the pipeline catches this.
Suggested fix
Detect the <expr> ? "" : "s" / ? "s" : "" ternary shape (and near-variants) during interpolation conversion and emit a plural keyed on the numeric variable, rather than a select on the boolean. Where the shape can't be recognised confidently, prefer the existing "skip with a warning" path over emitting a message that is silently unlocalizable — spec 005 §10.4 already establishes that convention for complex expressions.
Worth widening the quantity-name heuristic too (remaining, left, items, …), though a shape-based rule is more reliable than a name-based one.
Environment
Reproduced with mur built from 88ef6db4.
Summary
mur loc extractconverts a C# ternary used for pluralization into an ICUselectkeyed on an English boolean. The result renders correctly in English but cannot be translated into any language whose plural rules differ from English — which defeats the purpose of the tool.Repro
samples/TodoApp/Program.cs:254:Extracted:
Why this is wrong
The message is valid — I verified it against the real runtime engine (
Jeffijoe.MessageFormat8.0.0, the ICU engine per spec 005 §11.1) and it formats fine in English:n=1n=3n=5murgenerated1 item left3 items left5 items leftThe defect is structural. The
onevsnot-onedecision was baked into C# at extract time, and the only branches exposed to a translator aretrueandfalse. Polish needs three plural forms; there is no branch to write the third in:n=1n=3n=5plural(pl-PL)1 element3 elementy5 elementówmurproducedThe correct extraction is a
plural, not aselect:pluraldelegates the category choice to CLDR at format time, so a translator can addfew/many.selecton a boolean freezes English grammar into the resource.Related problems in the same output
ItemFalseLeftis derived from message content including the literalfalsefrom the ternary.arg1is opaque to a translator. 27 of 561 values extracted fromsamples/ReactorGallerycarryarg{n}-style placeholders.consider adding plural support) when it detects a variable namedcount,total,num*, or similar quantity-suggesting names."remainingisn't in that list, so nothing warned — the broken message was emitted silently.mur loc validatepasses it. Its stated job is "Check ICU syntax and parameter consistency"; the message is syntactically valid, so it reportsValidation passed: no errors or warnings.Nothing in the pipeline catches this.Suggested fix
Detect the
<expr> ? "" : "s"/? "s" : ""ternary shape (and near-variants) during interpolation conversion and emit apluralkeyed on the numeric variable, rather than aselecton the boolean. Where the shape can't be recognised confidently, prefer the existing "skip with a warning" path over emitting a message that is silently unlocalizable — spec 005 §10.4 already establishes that convention for complex expressions.Worth widening the quantity-name heuristic too (
remaining,left,items, …), though a shape-based rule is more reliable than a name-based one.Environment
Reproduced with
murbuilt from88ef6db4.