From 3df2f4c6022346a561d256c6036f8a39cc802700 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9gis=20Fricker?= Date: Mon, 19 Aug 2019 10:40:24 +0200 Subject: [PATCH 1/2] Allow to have 2 messages with same name but not same GenericParameters count. --- .../MessageDsl/CSharpGeneratorTests.cs | 30 ++++++++++++++++++- .../MessageDsl/ParsedContractsTests.cs | 20 +++++++++++++ .../Analysis/AstValidator.cs | 22 ++++++++++---- 3 files changed, 65 insertions(+), 7 deletions(-) diff --git a/src/Abc.Zebus.MessageDsl.Tests/MessageDsl/CSharpGeneratorTests.cs b/src/Abc.Zebus.MessageDsl.Tests/MessageDsl/CSharpGeneratorTests.cs index c76deb1..6875888 100644 --- a/src/Abc.Zebus.MessageDsl.Tests/MessageDsl/CSharpGeneratorTests.cs +++ b/src/Abc.Zebus.MessageDsl.Tests/MessageDsl/CSharpGeneratorTests.cs @@ -1,4 +1,5 @@ -using Abc.Zebus.MessageDsl.Ast; +using System; +using Abc.Zebus.MessageDsl.Ast; using Abc.Zebus.MessageDsl.Generator; using Abc.Zebus.MessageDsl.Tests.TestTools; using NUnit.Framework; @@ -451,6 +452,33 @@ public void should_leave_supplied_protomap() code.ShouldNotContain("ProtoMap(DisableMap = true)"); } + [Test] + public void should_generate_two_class() + { + // Arrange + var msg1 = new MessageDefinition(); + msg1.Name = "GenericCommand"; + var msg2 = new MessageDefinition(); + msg2.Name = msg1.Name; + msg2.GenericParameters.Add("IEnumerable"); + var contracts = new ParsedContracts(); + contracts.Messages.Add(msg1); + contracts.Messages.Add(msg2); + contracts.ImportedNamespaces.Add("System.Collections"); + + // Act + var result = GenerateRaw(contracts); + + // Assert + Console.WriteLine("----- START -----"); + Console.WriteLine(result); + Console.WriteLine("----- END -----"); + + contracts.Errors.ShouldBeEmpty(); + result.ShouldContain("public sealed partial class GenericCommand"); + result.ShouldContain("public sealed partial class GenericCommand"); + } + protected override string GenerateRaw(ParsedContracts contracts) => CSharpGenerator.Generate(contracts); } } diff --git a/src/Abc.Zebus.MessageDsl.Tests/MessageDsl/ParsedContractsTests.cs b/src/Abc.Zebus.MessageDsl.Tests/MessageDsl/ParsedContractsTests.cs index 7624c2c..59d8b10 100644 --- a/src/Abc.Zebus.MessageDsl.Tests/MessageDsl/ParsedContractsTests.cs +++ b/src/Abc.Zebus.MessageDsl.Tests/MessageDsl/ParsedContractsTests.cs @@ -498,6 +498,26 @@ public void should_return_source_text() attr.GetSourceTextInterval().ShouldEqual(new TextInterval(3, 11)); } + [Test] + public void should_return_two_messages() + { + // Arrange + var name = "Command"; + var genericParam = "IEnumerable"; + var definitionText = "using System.Collections;" + Environment.NewLine + + $"{name}()" + Environment.NewLine + + $"{name}<{genericParam}>()"; + + // Act + var contracts = ParseValid(definitionText); + + // Assert + contracts.Messages.Count.ShouldEqual(2); + contracts.Messages[0].Name.ShouldEqual(name); + contracts.Messages[1].Name.ShouldEqual(name); + contracts.Messages[1].GenericParameters.ExpectedSingle().ShouldEqual(genericParam); + } + private static ParsedContracts ParseValid(string definitionText) { var contracts = Parse(definitionText); diff --git a/src/Abc.Zebus.MessageDsl/Analysis/AstValidator.cs b/src/Abc.Zebus.MessageDsl/Analysis/AstValidator.cs index 8d8c3c8..61e2118 100644 --- a/src/Abc.Zebus.MessageDsl/Analysis/AstValidator.cs +++ b/src/Abc.Zebus.MessageDsl/Analysis/AstValidator.cs @@ -99,21 +99,31 @@ private void DetectDuplicateTypes() foreach (var typeNode in types) { - var name = ((INamedNode)typeNode).Name; + var id = Id(typeNode); - if (!seenTypes.Add(name)) - duplicates.Add(name); + if (!seenTypes.Add(id)) + duplicates.Add(id); } foreach (var typeNode in types) { - var name = ((INamedNode)typeNode).Name; + var id = Id(typeNode); - if (duplicates.Contains(name)) - _contracts.AddError(typeNode.ParseContext, "Duplicate type name: {0}", name); + if (duplicates.Contains(id)) + _contracts.AddError(typeNode.ParseContext, "Duplicate type id: {0}", id); } } + private string Id(AstNode node) + { + var name = ((INamedNode)node).Name; + if (node is MessageDefinition messageDef && messageDef.GenericParameters.Count > 0) + { + name = $"{name}-{messageDef.GenericParameters.Count}"; + } + return name; + } + public static bool IsValidTag(int tag) { return tag >= ProtoMinTag && tag <= ProtoMaxTag From e29199519c542ddd999b52820cddd7f15b30adb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9gis=20Fricker?= Date: Mon, 19 Aug 2019 11:54:51 +0200 Subject: [PATCH 2/2] handle PR responses. --- .../MessageDsl/CSharpGeneratorTests.cs | 11 +++----- .../MessageDsl/ParsedContractsTests.cs | 9 +++---- .../Analysis/AstValidator.cs | 26 +++++++++---------- 3 files changed, 20 insertions(+), 26 deletions(-) diff --git a/src/Abc.Zebus.MessageDsl.Tests/MessageDsl/CSharpGeneratorTests.cs b/src/Abc.Zebus.MessageDsl.Tests/MessageDsl/CSharpGeneratorTests.cs index 6875888..6306d05 100644 --- a/src/Abc.Zebus.MessageDsl.Tests/MessageDsl/CSharpGeneratorTests.cs +++ b/src/Abc.Zebus.MessageDsl.Tests/MessageDsl/CSharpGeneratorTests.cs @@ -453,30 +453,25 @@ public void should_leave_supplied_protomap() } [Test] - public void should_generate_two_class() + public void should_generate_two_classes_with_same_name_and_different_arity() { // Arrange var msg1 = new MessageDefinition(); msg1.Name = "GenericCommand"; var msg2 = new MessageDefinition(); msg2.Name = msg1.Name; - msg2.GenericParameters.Add("IEnumerable"); + msg2.GenericParameters.Add("T"); var contracts = new ParsedContracts(); contracts.Messages.Add(msg1); contracts.Messages.Add(msg2); - contracts.ImportedNamespaces.Add("System.Collections"); // Act var result = GenerateRaw(contracts); // Assert - Console.WriteLine("----- START -----"); - Console.WriteLine(result); - Console.WriteLine("----- END -----"); - contracts.Errors.ShouldBeEmpty(); result.ShouldContain("public sealed partial class GenericCommand"); - result.ShouldContain("public sealed partial class GenericCommand"); + result.ShouldContain("public sealed partial class GenericCommand"); } protected override string GenerateRaw(ParsedContracts contracts) => CSharpGenerator.Generate(contracts); diff --git a/src/Abc.Zebus.MessageDsl.Tests/MessageDsl/ParsedContractsTests.cs b/src/Abc.Zebus.MessageDsl.Tests/MessageDsl/ParsedContractsTests.cs index 59d8b10..a0b786f 100644 --- a/src/Abc.Zebus.MessageDsl.Tests/MessageDsl/ParsedContractsTests.cs +++ b/src/Abc.Zebus.MessageDsl.Tests/MessageDsl/ParsedContractsTests.cs @@ -499,13 +499,12 @@ public void should_return_source_text() } [Test] - public void should_return_two_messages() + public void should_return_two_messages_with_same_name_but_different_arity() { // Arrange - var name = "Command"; - var genericParam = "IEnumerable"; - var definitionText = "using System.Collections;" + Environment.NewLine + - $"{name}()" + Environment.NewLine + + var name = "Foo"; + var genericParam = "T"; + var definitionText = $"{name}()" + Environment.NewLine + $"{name}<{genericParam}>()"; // Act diff --git a/src/Abc.Zebus.MessageDsl/Analysis/AstValidator.cs b/src/Abc.Zebus.MessageDsl/Analysis/AstValidator.cs index 61e2118..b1a9089 100644 --- a/src/Abc.Zebus.MessageDsl/Analysis/AstValidator.cs +++ b/src/Abc.Zebus.MessageDsl/Analysis/AstValidator.cs @@ -99,29 +99,29 @@ private void DetectDuplicateTypes() foreach (var typeNode in types) { - var id = Id(typeNode); + var nameWithGenericArity = GetNameWithGenericArity(typeNode); - if (!seenTypes.Add(id)) - duplicates.Add(id); + if (!seenTypes.Add(nameWithGenericArity)) + duplicates.Add(nameWithGenericArity); } foreach (var typeNode in types) { - var id = Id(typeNode); + var nameWithGenericArity = GetNameWithGenericArity(typeNode); - if (duplicates.Contains(id)) - _contracts.AddError(typeNode.ParseContext, "Duplicate type id: {0}", id); + if (duplicates.Contains(nameWithGenericArity)) + _contracts.AddError(typeNode.ParseContext, "Duplicate type name: {0}", nameWithGenericArity); } - } - private string Id(AstNode node) - { - var name = ((INamedNode)node).Name; - if (node is MessageDefinition messageDef && messageDef.GenericParameters.Count > 0) + string GetNameWithGenericArity(AstNode node) { - name = $"{name}-{messageDef.GenericParameters.Count}"; + var name = ((INamedNode)node).Name; + if (node is MessageDefinition messageDef && messageDef.GenericParameters.Count > 0) + { + name = $"{name}`{messageDef.GenericParameters.Count}"; + } + return name; } - return name; } public static bool IsValidTag(int tag)