From 45a4369acd36f654589a160219e5f820d26cb3ea Mon Sep 17 00:00:00 2001 From: daver32 <38791383+daver32@users.noreply.github.com> Date: Fri, 28 Jan 2022 12:01:02 +0100 Subject: [PATCH] Added prefixing for method params that have the same name as a C# keyword --- .../MethodGenerationTests.cs | 22 +++ InterfaceGenerator/AutoInterfaceGenerator.cs | 10 +- InterfaceGenerator/StringExtensions.cs | 125 ++++++++++++++++++ 3 files changed, 156 insertions(+), 1 deletion(-) create mode 100644 InterfaceGenerator/StringExtensions.cs diff --git a/InterfaceGenerator.Tests/MethodGenerationTests.cs b/InterfaceGenerator.Tests/MethodGenerationTests.cs index 53aec89..34a55eb 100644 --- a/InterfaceGenerator.Tests/MethodGenerationTests.cs +++ b/InterfaceGenerator.Tests/MethodGenerationTests.cs @@ -31,6 +31,24 @@ namespace InterfaceGenerator.Tests _sut.VoidMethod(); } + [Fact] + public void VoidMethodWithKeywordParam_IsImplemented() + { + var method = typeof(IMethodsTestService).GetMethod( + nameof(MethodsTestService.VoidMethodWithKeywordParam)); + + method.Should().NotBeNull(); + method.ReturnType.Should().Be(typeof(void)); + + var parameters = method.GetParameters(); + parameters.Select(x => x.ParameterType).Should().AllBeEquivalentTo(typeof(string)); + parameters.Should().HaveCount(1); + + parameters[0].Name.Should().Be("void"); + + _sut.VoidMethodWithKeywordParam(""); + } + [Fact] public void VoidMethodWithParams_IsImplemented() { @@ -257,6 +275,10 @@ namespace InterfaceGenerator.Tests public void VoidMethodWithParams(string a, string b) { } + + public void VoidMethodWithKeywordParam(string @void) + { + } public void VoidMethodWithOutParam(out string a) { diff --git a/InterfaceGenerator/AutoInterfaceGenerator.cs b/InterfaceGenerator/AutoInterfaceGenerator.cs index b06f513..8502761 100644 --- a/InterfaceGenerator/AutoInterfaceGenerator.cs +++ b/InterfaceGenerator/AutoInterfaceGenerator.cs @@ -323,8 +323,16 @@ namespace InterfaceGenerator writer.Write("in "); break; } + + writer.Write(param.Type); + writer.Write(" "); - writer.Write("{0} {1}", param.Type, param.Name); + if (StringExtensions.IsCSharpKeyword(param.Name)) + { + writer.Write("@"); + } + + writer.Write(param.Name); if (param.HasExplicitDefaultValue) { diff --git a/InterfaceGenerator/StringExtensions.cs b/InterfaceGenerator/StringExtensions.cs new file mode 100644 index 0000000..8859a69 --- /dev/null +++ b/InterfaceGenerator/StringExtensions.cs @@ -0,0 +1,125 @@ +namespace InterfaceGenerator +{ + internal static class StringExtensions + { + public static bool IsCSharpKeyword(string? name) + { + switch (name) + { + case "abstract": + case "add": + case "alias": + case "as": + case "ascending": + case "async": + case "await": + case "base": + case "bool": + case "break": + case "by": + case "byte": + case "case": + case "catch": + case "char": + case "checked": + case "class": + case "const": + case "continue": + case "decimal": + case "default": + case "delegate": + case "descending": + case "do": + case "double": + case "dynamic": + case "else": + case "enum": + case "equals": + case "event": + case "explicit": + case "extern": + case "false": + case "finally": + case "fixed": + case "float": + case "for": + case "foreach": + case "from": + case "get": + case "global": + case "goto": + // `group` is a contextual to linq queries that we don't generate + //case "group": + case "if": + case "implicit": + case "in": + case "int": + case "interface": + case "internal": + case "into": + case "is": + case "join": + case "let": + case "lock": + case "long": + case "nameof": + case "namespace": + case "new": + case "null": + case "object": + case "on": + case "operator": + // `orderby` is a contextual to linq queries that we don't generate + //case "orderby": + case "out": + case "override": + case "params": + case "partial": + case "private": + case "protected": + case "public": + case "readonly": + case "ref": + case "remove": + case "return": + case "sbyte": + case "sealed": + // `select` is a contextual to linq queries that we don't generate + // case "select": + case "set": + case "short": + case "sizeof": + case "stackalloc": + case "static": + case "string": + case "struct": + case "switch": + case "this": + case "throw": + case "true": + case "try": + case "typeof": + case "uint": + case "ulong": + case "unchecked": + case "unmanaged": + case "unsafe": + case "ushort": + case "using": + // `value` is a contextual to getters that we don't generate + // case "value": + case "var": + case "virtual": + case "void": + case "volatile": + case "when": + case "where": + case "while": + case "yield": + return true; + default: + return false; + } + } + } +} \ No newline at end of file