ThisAssembly
ThisAssembly copied to clipboard
ThisAssembly.Strings: If resource name is not a valid code identifier, compilation fails
If a resx file contains an entry with an invalid code identifier (like a number), the generated code will not compile, and the error is quite cryptic too.
We should validate that the name are valid C# identifiers and skip (probably warn too if they aren't?)
Some quick notes:
- The same check may be useful in other situations where identifiers are involved, e.g. user-defined constants.
- Roslyn has a handy IsValidIdentifier utility method that can be used for this purpose.
- There's an IsValidIdentifier method for Visual Basic too, so you may call one or the other according to the project's language.
- F# is no concern, as it doesn't support code generators.
I guess more than just checking whether the identifier is valid, you'd actually want it to generate code but turn the identifier into a valid one by replacing invalid chars with underscores, say...
@viceroypenguin perhaps this could also use the sanitization you applied to resource class names?
Yeah, I encountered this while working on Resources; I just got lazy and avoided it for now... 🙂. I would expect the code to work the same here. Could copy/paste or extract to common .cs file. The regex is doing the bulk of the work, so copy/paste would probably be fine.
This method could be used to generate a valid identifier : it replaces any invalid identifier by '', removes redundant '', and prefixes the identifier by '_' if not valid :
private string EscapeIdentifier(string filename)
{
var bytes = filename.ToCharArray();
var replaced = bytes.Select(_ => SyntaxFacts.IsIdentifierPartCharacter(_) ? _ : '_').ToArray();
var result = Regex.Replace(new string(replaced), "(_)+", "_");
if (!SyntaxFacts.IsValidIdentifier(result))
{
result = "_" + result;
}
return result;
}
As for now, all we can do is change all the files' name, but that's not always easy.
Thanks for the suggestion @PhenX. Would you like to send a PR? 🙏