From 643e51dbfaeeb133f434e8ca2959f4bc495db2fa Mon Sep 17 00:00:00 2001 From: George Barnett Date: Wed, 20 Nov 2024 15:38:27 +0000 Subject: [PATCH] Simplify typealias translator Motivation: The typealias used to generte an enum per package name and nested enums for each service within that namespace. In order for that to work, the services had to be grouped by namespace. This is no longer the case, each service is generated within a combined package-service enum. It's simpler to just generate the services in the order they are created. Modifications: - Remove the sorting - Remove tests which test the unwanted behaviour Result: Less code --- .../Translator/TypealiasTranslator.swift | 27 +- ...TypealiasTranslatorSnippetBasedTests.swift | 369 ------------------ 2 files changed, 12 insertions(+), 384 deletions(-) diff --git a/Sources/GRPCCodeGen/Internal/Translator/TypealiasTranslator.swift b/Sources/GRPCCodeGen/Internal/Translator/TypealiasTranslator.swift index 7f36fe70e..8ae83f70e 100644 --- a/Sources/GRPCCodeGen/Internal/Translator/TypealiasTranslator.swift +++ b/Sources/GRPCCodeGen/Internal/Translator/TypealiasTranslator.swift @@ -81,25 +81,22 @@ struct TypealiasTranslator: SpecializedTranslator { func translate(from codeGenerationRequest: CodeGenerationRequest) throws -> [CodeBlock] { var codeBlocks = [CodeBlock]() - let services = codeGenerationRequest.services - let servicesByEnumName = Dictionary( - grouping: services, - by: { $0.namespacedGeneratedName } - ) - // Sorting the keys of the dictionary is necessary so that the generated enums are deterministically ordered. - for (generatedEnumName, services) in servicesByEnumName.sorted(by: { $0.key < $1.key }) { - for service in services { - codeBlocks.append( - CodeBlock( - item: .declaration(try self.makeServiceEnum(from: service, named: generatedEnumName)) + for service in codeGenerationRequest.services { + codeBlocks.append( + CodeBlock( + item: .declaration( + try self.makeServiceEnum( + from: service, + named: service.namespacedGeneratedName + ) ) ) + ) - codeBlocks.append( - CodeBlock(item: .declaration(self.makeServiceDescriptorExtension(for: service))) - ) - } + codeBlocks.append( + CodeBlock(item: .declaration(self.makeServiceDescriptorExtension(for: service))) + ) } return codeBlocks diff --git a/Tests/GRPCCodeGenTests/Internal/Translator/TypealiasTranslatorSnippetBasedTests.swift b/Tests/GRPCCodeGenTests/Internal/Translator/TypealiasTranslatorSnippetBasedTests.swift index 658a41b66..a8294ef31 100644 --- a/Tests/GRPCCodeGenTests/Internal/Translator/TypealiasTranslatorSnippetBasedTests.swift +++ b/Tests/GRPCCodeGenTests/Internal/Translator/TypealiasTranslatorSnippetBasedTests.swift @@ -301,85 +301,6 @@ final class TypealiasTranslatorSnippetBasedTests: XCTestCase { ) } - func testTypealiasTranslatorCheckMethodsOrder() throws { - let methodA = MethodDescriptor( - documentation: "Documentation for MethodA", - name: Name(base: "MethodA", generatedUpperCase: "MethodA", generatedLowerCase: "methodA"), - isInputStreaming: false, - isOutputStreaming: false, - inputType: "NamespaceA_ServiceARequest", - outputType: "NamespaceA_ServiceAResponse" - ) - let methodB = MethodDescriptor( - documentation: "Documentation for MethodB", - name: Name(base: "MethodB", generatedUpperCase: "MethodB", generatedLowerCase: "methodB"), - isInputStreaming: false, - isOutputStreaming: false, - inputType: "NamespaceA_ServiceARequest", - outputType: "NamespaceA_ServiceAResponse" - ) - let service = ServiceDescriptor( - documentation: "Documentation for ServiceA", - name: Name(base: "ServiceA", generatedUpperCase: "ServiceA", generatedLowerCase: "serviceA"), - namespace: Name( - base: "namespaceA", - generatedUpperCase: "NamespaceA", - generatedLowerCase: "namespaceA" - ), - methods: [methodA, methodB] - ) - let expectedSwift = - """ - public enum NamespaceA_ServiceA { - public static let descriptor = GRPCCore.ServiceDescriptor.namespaceA_ServiceA - public enum Method { - public enum MethodA { - public typealias Input = NamespaceA_ServiceARequest - public typealias Output = NamespaceA_ServiceAResponse - public static let descriptor = GRPCCore.MethodDescriptor( - service: NamespaceA_ServiceA.descriptor.fullyQualifiedService, - method: "MethodA" - ) - } - public enum MethodB { - public typealias Input = NamespaceA_ServiceARequest - public typealias Output = NamespaceA_ServiceAResponse - public static let descriptor = GRPCCore.MethodDescriptor( - service: NamespaceA_ServiceA.descriptor.fullyQualifiedService, - method: "MethodB" - ) - } - public static let descriptors: [GRPCCore.MethodDescriptor] = [ - MethodA.descriptor, - MethodB.descriptor - ] - } - @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) - public typealias StreamingServiceProtocol = NamespaceA_ServiceA_StreamingServiceProtocol - @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) - public typealias ServiceProtocol = NamespaceA_ServiceA_ServiceProtocol - @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) - public typealias ClientProtocol = NamespaceA_ServiceA_ClientProtocol - @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) - public typealias Client = NamespaceA_ServiceA_Client - } - extension GRPCCore.ServiceDescriptor { - public static let namespaceA_ServiceA = Self( - package: "namespaceA", - service: "ServiceA" - ) - } - """ - - try self.assertTypealiasTranslation( - codeGenerationRequest: makeCodeGenerationRequest(services: [service]), - expectedSwift: expectedSwift, - client: true, - server: true, - accessLevel: .public - ) - } - func testTypealiasTranslatorNoMethodsService() throws { let service = ServiceDescriptor( documentation: "Documentation for ServiceA", @@ -423,296 +344,6 @@ final class TypealiasTranslatorSnippetBasedTests: XCTestCase { accessLevel: .package ) } - - func testTypealiasTranslatorServiceAlphabeticalOrder() throws { - let serviceB = ServiceDescriptor( - documentation: "Documentation for BService", - name: Name(base: "BService", generatedUpperCase: "Bservice", generatedLowerCase: "bservice"), - namespace: Name( - base: "namespaceA", - generatedUpperCase: "NamespaceA", - generatedLowerCase: "namespaceA" - ), - methods: [] - ) - - let serviceA = ServiceDescriptor( - documentation: "Documentation for AService", - name: Name(base: "AService", generatedUpperCase: "Aservice", generatedLowerCase: "aservice"), - namespace: Name( - base: "namespaceA", - generatedUpperCase: "NamespaceA", - generatedLowerCase: "namespaceA" - ), - methods: [] - ) - - let expectedSwift = - """ - public enum NamespaceA_Aservice { - public static let descriptor = GRPCCore.ServiceDescriptor.namespaceA_AService - public enum Method { - public static let descriptors: [GRPCCore.MethodDescriptor] = [] - } - @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) - public typealias StreamingServiceProtocol = NamespaceA_Aservice_StreamingServiceProtocol - @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) - public typealias ServiceProtocol = NamespaceA_Aservice_ServiceProtocol - @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) - public typealias ClientProtocol = NamespaceA_Aservice_ClientProtocol - @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) - public typealias Client = NamespaceA_Aservice_Client - } - extension GRPCCore.ServiceDescriptor { - public static let namespaceA_AService = Self( - package: "namespaceA", - service: "AService" - ) - } - public enum NamespaceA_Bservice { - public static let descriptor = GRPCCore.ServiceDescriptor.namespaceA_BService - public enum Method { - public static let descriptors: [GRPCCore.MethodDescriptor] = [] - } - @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) - public typealias StreamingServiceProtocol = NamespaceA_Bservice_StreamingServiceProtocol - @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) - public typealias ServiceProtocol = NamespaceA_Bservice_ServiceProtocol - @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) - public typealias ClientProtocol = NamespaceA_Bservice_ClientProtocol - @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) - public typealias Client = NamespaceA_Bservice_Client - } - extension GRPCCore.ServiceDescriptor { - public static let namespaceA_BService = Self( - package: "namespaceA", - service: "BService" - ) - } - """ - - try self.assertTypealiasTranslation( - codeGenerationRequest: makeCodeGenerationRequest(services: [serviceB, serviceA]), - expectedSwift: expectedSwift, - client: true, - server: true, - accessLevel: .public - ) - } - - func testTypealiasTranslatorServiceAlphabeticalOrderNoNamespace() throws { - let serviceB = ServiceDescriptor( - documentation: "Documentation for BService", - name: Name(base: "BService", generatedUpperCase: "BService", generatedLowerCase: "bservice"), - namespace: Name(base: "", generatedUpperCase: "", generatedLowerCase: ""), - methods: [] - ) - - let serviceA = ServiceDescriptor( - documentation: "Documentation for AService", - name: Name(base: "AService", generatedUpperCase: "AService", generatedLowerCase: "aservice"), - namespace: Name(base: "", generatedUpperCase: "", generatedLowerCase: ""), - methods: [] - ) - - let expectedSwift = - """ - package enum AService { - package static let descriptor = GRPCCore.ServiceDescriptor.AService - package enum Method { - package static let descriptors: [GRPCCore.MethodDescriptor] = [] - } - @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) - package typealias StreamingServiceProtocol = AService_StreamingServiceProtocol - @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) - package typealias ServiceProtocol = AService_ServiceProtocol - @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) - package typealias ClientProtocol = AService_ClientProtocol - @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) - package typealias Client = AService_Client - } - extension GRPCCore.ServiceDescriptor { - package static let AService = Self( - package: "", - service: "AService" - ) - } - package enum BService { - package static let descriptor = GRPCCore.ServiceDescriptor.BService - package enum Method { - package static let descriptors: [GRPCCore.MethodDescriptor] = [] - } - @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) - package typealias StreamingServiceProtocol = BService_StreamingServiceProtocol - @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) - package typealias ServiceProtocol = BService_ServiceProtocol - @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) - package typealias ClientProtocol = BService_ClientProtocol - @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) - package typealias Client = BService_Client - } - extension GRPCCore.ServiceDescriptor { - package static let BService = Self( - package: "", - service: "BService" - ) - } - """ - - try self.assertTypealiasTranslation( - codeGenerationRequest: makeCodeGenerationRequest(services: [serviceB, serviceA]), - expectedSwift: expectedSwift, - client: true, - server: true, - accessLevel: .package - ) - } - - func testTypealiasTranslatorNamespaceAlphabeticalOrder() throws { - let serviceB = ServiceDescriptor( - documentation: "Documentation for BService", - name: Name(base: "BService", generatedUpperCase: "BService", generatedLowerCase: "bservice"), - namespace: Name( - base: "bnamespace", - generatedUpperCase: "Bnamespace", - generatedLowerCase: "bnamespace" - ), - methods: [] - ) - - let serviceA = ServiceDescriptor( - documentation: "Documentation for AService", - name: Name(base: "AService", generatedUpperCase: "AService", generatedLowerCase: "aservice"), - namespace: Name( - base: "anamespace", - generatedUpperCase: "Anamespace", - generatedLowerCase: "anamespace" - ), - methods: [] - ) - - let expectedSwift = - """ - internal enum Anamespace_AService { - internal static let descriptor = GRPCCore.ServiceDescriptor.anamespace_AService - internal enum Method { - internal static let descriptors: [GRPCCore.MethodDescriptor] = [] - } - @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) - internal typealias StreamingServiceProtocol = Anamespace_AService_StreamingServiceProtocol - @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) - internal typealias ServiceProtocol = Anamespace_AService_ServiceProtocol - @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) - internal typealias ClientProtocol = Anamespace_AService_ClientProtocol - @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) - internal typealias Client = Anamespace_AService_Client - } - extension GRPCCore.ServiceDescriptor { - internal static let anamespace_AService = Self( - package: "anamespace", - service: "AService" - ) - } - internal enum Bnamespace_BService { - internal static let descriptor = GRPCCore.ServiceDescriptor.bnamespace_BService - internal enum Method { - internal static let descriptors: [GRPCCore.MethodDescriptor] = [] - } - @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) - internal typealias StreamingServiceProtocol = Bnamespace_BService_StreamingServiceProtocol - @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) - internal typealias ServiceProtocol = Bnamespace_BService_ServiceProtocol - @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) - internal typealias ClientProtocol = Bnamespace_BService_ClientProtocol - @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) - internal typealias Client = Bnamespace_BService_Client - } - extension GRPCCore.ServiceDescriptor { - internal static let bnamespace_BService = Self( - package: "bnamespace", - service: "BService" - ) - } - """ - - try self.assertTypealiasTranslation( - codeGenerationRequest: makeCodeGenerationRequest(services: [serviceB, serviceA]), - expectedSwift: expectedSwift, - client: true, - server: true, - accessLevel: .internal - ) - } - - func testTypealiasTranslatorNamespaceNoNamespaceOrder() throws { - let serviceA = ServiceDescriptor( - documentation: "Documentation for AService", - name: Name(base: "AService", generatedUpperCase: "AService", generatedLowerCase: "aService"), - namespace: Name( - base: "anamespace", - generatedUpperCase: "Anamespace", - generatedLowerCase: "anamespace" - ), - methods: [] - ) - let serviceB = ServiceDescriptor( - documentation: "Documentation for BService", - name: Name(base: "BService", generatedUpperCase: "BService", generatedLowerCase: "bService"), - namespace: Name(base: "", generatedUpperCase: "", generatedLowerCase: ""), - methods: [] - ) - let expectedSwift = - """ - public enum Anamespace_AService { - public static let descriptor = GRPCCore.ServiceDescriptor.anamespace_AService - public enum Method { - public static let descriptors: [GRPCCore.MethodDescriptor] = [] - } - @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) - public typealias StreamingServiceProtocol = Anamespace_AService_StreamingServiceProtocol - @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) - public typealias ServiceProtocol = Anamespace_AService_ServiceProtocol - @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) - public typealias ClientProtocol = Anamespace_AService_ClientProtocol - @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) - public typealias Client = Anamespace_AService_Client - } - extension GRPCCore.ServiceDescriptor { - public static let anamespace_AService = Self( - package: "anamespace", - service: "AService" - ) - } - public enum BService { - public static let descriptor = GRPCCore.ServiceDescriptor.BService - public enum Method { - public static let descriptors: [GRPCCore.MethodDescriptor] = [] - } - @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) - public typealias StreamingServiceProtocol = BService_StreamingServiceProtocol - @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) - public typealias ServiceProtocol = BService_ServiceProtocol - @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) - public typealias ClientProtocol = BService_ClientProtocol - @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) - public typealias Client = BService_Client - } - extension GRPCCore.ServiceDescriptor { - public static let BService = Self( - package: "", - service: "BService" - ) - } - """ - - try self.assertTypealiasTranslation( - codeGenerationRequest: makeCodeGenerationRequest(services: [serviceA, serviceB]), - expectedSwift: expectedSwift, - client: true, - server: true, - accessLevel: .public - ) - } } extension TypealiasTranslatorSnippetBasedTests {