From ef50249d316c83a5481b9826f8809d1241eefeee Mon Sep 17 00:00:00 2001 From: Simon Pilkington Date: Mon, 26 Sep 2022 15:32:22 -0700 Subject: [PATCH 1/2] Support custom target names. --- README.md | 124 ++++++++++++++++-- .../ModelClientDelegate.swift | 18 +-- .../ServiceModelCodeGenerator.swift | 25 +++- .../ClientProtocolDelegate.swift | 19 +-- .../MockClientDelegate.swift | 30 ++--- ...CodeGenerator+addGeneratedFileHeader.swift | 30 +++++ ...deGenerator+addRequestInputStructure.swift | 4 +- ...or+createOutputStructureStubVariable.swift | 10 +- ...enerator+createStructureStubVariable.swift | 10 +- ...iceModelCodeGenerator+generateClient.swift | 96 +++++++------- ...enerator+generateConversionFunctions.swift | 30 ++--- ...deGenerator+generateDefaultInstances.swift | 11 +- ...rator+generateEnumerationDeclaration.swift | 8 +- ...delCodeGenerator+generateModelErrors.swift | 7 +- ...or+generateModelInvocationsReporting.swift | 12 +- ...or+generateModelOperationClientInput.swift | 26 ++-- ...r+generateModelOperationClientOutput.swift | 10 +- ...enerator+generateModelOperationsEnum.swift | 7 +- ...tor+generateModelOperationsReporting.swift | 12 +- ...odeGenerator+generateModelStructures.swift | 9 +- ...odelCodeGenerator+generateModelTypes.swift | 7 +- ...ceModelCodeGenerator+shapeConversion.swift | 30 +++-- ...viceModelCodeGenerator+shapeProtocol.swift | 10 +- ...delCodeGenerator+validationFunctions.swift | 8 +- .../ServiceModelGenerate.swift | 103 +++++++++++++-- 25 files changed, 453 insertions(+), 203 deletions(-) create mode 100644 Sources/ServiceModelGenerate/ServiceModelCodeGenerator+addGeneratedFileHeader.swift diff --git a/README.md b/README.md index a424e92..83f8c73 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,7 @@ will attempt to parse that file into the required service model type and will th to the provided function which can call any required generation functions. ```swift -extension ServiceModelCodeGenerator { +extension ServiceModelCodeGenerator where TargetSupportType: ModelTargetSupport & ClientTargetSupport { func generateFromModel(serviceModel: ModelType, ...) throws { @@ -62,28 +62,124 @@ extension ServiceModelCodeGenerator { } } +public struct MyCodeGeneration { + public static func generateFromModel( + modelFilePath: String, + modelType: ModelType.Type, + customizations: CodeGenerationCustomizations, + applicationDescription: ApplicationDescription, + modelOverride: ModelOverride?, + ...) throws + -> ModelType { + return try ServiceModelGenerate.generateFromModel( + modelFilePath: modelFilePath, + customizations: customizations, + applicationDescription: applicationDescription, + modelOverride: modelOverride) { (codeGenerator, serviceModel) in + try codeGenerator.generateFromModel(serviceModel: serviceModel, ...) + } + } +} +``` + +By default, the code generator will use `\(applicationDescription.baseName)Model` for the name of the model target and +`\(applicationDescription.baseName)Client` for the name of the client target. You can override these defaults by using +the `ModelAndClientTargetSupport` type. + +``` public struct MyCodeGeneration { - static let asyncResultType = AsyncResultType(typeName: "HTTPResult", - libraryImport: "SmokeHTTPClient") + public static func generateFromModel( + modelFilePath: String, + modelType: ModelType.Type, + modelTargetName: String, clientTargetName: String, + customizations: CodeGenerationCustomizations, + applicationDescription: ApplicationDescription, + modelOverride: ModelOverride?, + ...) throws + -> ModelType { + let targetSupport = ModelAndClientTargetSupport(modelTargetName: modelTargetName, + clientTargetName: clientTargetName) + + return try ServiceModelGenerate.generateFromModel( + modelFilePath: modelFilePath, + customizations: customizations, + applicationDescription: applicationDescription, + targetSupport: targetSupport, + modelOverride: modelOverride) { (codeGenerator, serviceModel) in + try codeGenerator.generateFromModel(serviceModel: serviceModel, ...) + } + } +} +``` + +Further, if you are generating additional targets, you can use a custom type that provides the name of +additional targets. This type will have to conform to the `ModelTargetSupport` and `ClientTargetSupport` protocols. + +```swift +extension ServiceModelCodeGenerator where TargetSupportType: ModelTargetSupport & ClientTargetSupport & MyCustomTargetSupport { + + func generateFromModel(serviceModel: ModelType, + ...) throws { + let myClientDelegate = ... + let myModelErrorsDelegate = ... + + generateClient(delegate: myClientDelegate) + generateModelOperationsEnum() + generateOperationsReporting() + generateModelOperationClientInput() + generateModelOperationClientOutput() + generateModelOperationHTTPInput() + generateModelOperationHTTPOutput() + generateModelStructures() + generateModelTypes() + generateModelErrors(delegate: myModelErrorsDelegate) + generateDefaultInstances(generationType: .internalTypes) + + // Call any custom generation functions as required + // The `targetSupport` attribute will conform to the `MyCustomTargetSupport` protocol. + } +} + +public protocol MyCustomTargetSupport { + var myCustomTargetName: String { get } +} + +public struct MyTargetSupport: ModelTargetSupport, ClientTargetSupport, MyCustomTargetSupport { + public let modelTargetName: String + public let clientTargetName: String + public let myCustomTargetName: String + public init(modelTargetName: String, clientTargetName: String, + myCustomTargetName: String) { + self.modelTargetName = modelTargetName + self.clientTargetName = clientTargetName + self.myCustomTargetName = myCustomTargetName + } +} + +public struct MyCodeGeneration { public static func generateFromModel( modelFilePath: String, modelType: ModelType.Type, + modelTargetName: String, clientTargetName: String, + myCustomTargetName: String, customizations: CodeGenerationCustomizations, applicationDescription: ApplicationDescription, modelOverride: ModelOverride?, - ...) throws { - func generatorFunction(codeGenerator: ServiceModelCodeGenerator, - serviceModel: ModelType) throws { + ...) throws + -> ModelType { + let targetSupport = MyTargetSupport(modelTargetName: modelTargetName, + clientTargetName: clientTargetName, + myCustomTargetName: myCustomTargetName) + + return try ServiceModelGenerate.generateFromModel( + modelFilePath: modelFilePath, + customizations: customizations, + applicationDescription: applicationDescription, + targetSupport: targetSupport, + modelOverride: modelOverride) { (codeGenerator, serviceModel) in try codeGenerator.generateFromModel(serviceModel: serviceModel, ...) - } - - try ServiceModelGenerate.generateFromModel( - modelFilePath: modelFilePath, - customizations: customizations, - applicationDescription: applicationDescription, - modelOverride: modelOverride, - generatorFunction: generatorFunction) + } } } ``` diff --git a/Sources/ServiceModelCodeGeneration/ModelClientDelegate.swift b/Sources/ServiceModelCodeGeneration/ModelClientDelegate.swift index cb22c8f..3860c1c 100644 --- a/Sources/ServiceModelCodeGeneration/ModelClientDelegate.swift +++ b/Sources/ServiceModelCodeGeneration/ModelClientDelegate.swift @@ -76,6 +76,8 @@ public enum ClientEntityType { from the Service Model. */ public protocol ModelClientDelegate { + associatedtype TargetSupportType + /// The type of client being generated. var clientType: ClientType { get } @@ -91,8 +93,8 @@ public protocol ModelClientDelegate { - delegate: the delegate being used. - fileBuilder: The FileBuilder to output to. */ - func addCustomFileHeader(codeGenerator: ServiceModelCodeGenerator, - delegate: ModelClientDelegate, + func addCustomFileHeader(codeGenerator: ServiceModelCodeGenerator, + delegate: Self, fileBuilder: FileBuilder, fileType: ClientFileType) @@ -104,8 +106,8 @@ public protocol ModelClientDelegate { - delegate: the delegate being used. - fileBuilder: The FileBuilder to output to. */ - func addTypeDescription(codeGenerator: ServiceModelCodeGenerator, - delegate: ModelClientDelegate, + func addTypeDescription(codeGenerator: ServiceModelCodeGenerator, + delegate: Self, fileBuilder: FileBuilder, entityType: ClientEntityType) @@ -118,8 +120,8 @@ public protocol ModelClientDelegate { - fileBuilder: The FileBuilder to output to. - sortedOperations: A list of sorted operations from the current model. */ - func addCommonFunctions(codeGenerator: ServiceModelCodeGenerator, - delegate: ModelClientDelegate, + func addCommonFunctions(codeGenerator: ServiceModelCodeGenerator, + delegate: Self, fileBuilder: FileBuilder, sortedOperations: [(String, OperationDescription)], entityType: ClientEntityType) @@ -137,8 +139,8 @@ public protocol ModelClientDelegate { - functionInputType: the input type to the operation. - functionOutputType: the output type for the operation. */ - func addOperationBody(codeGenerator: ServiceModelCodeGenerator, - delegate: ModelClientDelegate, + func addOperationBody(codeGenerator: ServiceModelCodeGenerator, + delegate: Self, fileBuilder: FileBuilder, invokeType: InvokeType, operationName: String, diff --git a/Sources/ServiceModelCodeGeneration/ServiceModelCodeGenerator.swift b/Sources/ServiceModelCodeGeneration/ServiceModelCodeGenerator.swift index dd95c6a..b862c26 100644 --- a/Sources/ServiceModelCodeGeneration/ServiceModelCodeGenerator.swift +++ b/Sources/ServiceModelCodeGeneration/ServiceModelCodeGenerator.swift @@ -18,12 +18,31 @@ import Foundation import ServiceModelEntities +public protocol ModelTargetSupport { + var modelTargetName: String { get } +} + +public protocol ClientTargetSupport { + var clientTargetName: String { get } +} + +public struct ModelAndClientTargetSupport: ModelTargetSupport, ClientTargetSupport { + public let modelTargetName: String + public let clientTargetName: String + + public init(modelTargetName: String, clientTargetName: String) { + self.modelTargetName = modelTargetName + self.clientTargetName = clientTargetName + } +} + /// A code generator that uses a Service Model -public struct ServiceModelCodeGenerator { +public struct ServiceModelCodeGenerator { public let model: ServiceModel public let applicationDescription: ApplicationDescription public let customizations: CodeGenerationCustomizations public let modelOverride: ModelOverride? + public let targetSupport: TargetSupportType /** Constructs the description with an application base name and suffix. @@ -40,11 +59,13 @@ public struct ServiceModelCodeGenerator { public init(model: ServiceModel, applicationDescription: ApplicationDescription, customizations: CodeGenerationCustomizations, - modelOverride: ModelOverride?) { + modelOverride: ModelOverride?, + targetSupport: TargetSupportType) { self.model = model self.applicationDescription = applicationDescription self.customizations = customizations self.modelOverride = modelOverride + self.targetSupport = targetSupport } } diff --git a/Sources/ServiceModelGenerate/ClientProtocolDelegate.swift b/Sources/ServiceModelGenerate/ClientProtocolDelegate.swift index ef2389f..e5de716 100644 --- a/Sources/ServiceModelGenerate/ClientProtocolDelegate.swift +++ b/Sources/ServiceModelGenerate/ClientProtocolDelegate.swift @@ -23,7 +23,8 @@ import ServiceModelEntities A ModelClientDelegate that can be used to generate a Client protocol from a Service Model. */ -public struct ClientProtocolDelegate: ModelClientDelegate { +public struct ClientProtocolDelegate: ModelClientDelegate +where TargetSupportType: ModelTargetSupport & ClientTargetSupport { public let clientType: ClientType public let baseName: String public let typeDescription: String @@ -49,22 +50,22 @@ public struct ClientProtocolDelegate: ModelClientDelegate { self.minimumCompilerSupport = minimumCompilerSupport } - public func addTypeDescription(codeGenerator: ServiceModelCodeGenerator, - delegate: ModelClientDelegate, + public func addTypeDescription(codeGenerator: ServiceModelCodeGenerator, + delegate: Self, fileBuilder: FileBuilder, entityType: ClientEntityType) { fileBuilder.appendLine(self.typeDescription) } - public func addCustomFileHeader(codeGenerator: ServiceModelCodeGenerator, - delegate: ModelClientDelegate, + public func addCustomFileHeader(codeGenerator: ServiceModelCodeGenerator, + delegate: Self, fileBuilder: FileBuilder, fileType: ClientFileType) { // no custom file header } - public func addCommonFunctions(codeGenerator: ServiceModelCodeGenerator, - delegate: ModelClientDelegate, + public func addCommonFunctions(codeGenerator: ServiceModelCodeGenerator, + delegate: Self, fileBuilder: FileBuilder, sortedOperations: [(String, OperationDescription)], entityType: ClientEntityType) { @@ -124,8 +125,8 @@ public struct ClientProtocolDelegate: ModelClientDelegate { } } - public func addOperationBody(codeGenerator: ServiceModelCodeGenerator, - delegate: ModelClientDelegate, + public func addOperationBody(codeGenerator: ServiceModelCodeGenerator, + delegate: Self, fileBuilder: FileBuilder, invokeType: InvokeType, operationName: String, operationDescription: OperationDescription, diff --git a/Sources/ServiceModelGenerate/MockClientDelegate.swift b/Sources/ServiceModelGenerate/MockClientDelegate.swift index 2a9959b..e586c06 100644 --- a/Sources/ServiceModelGenerate/MockClientDelegate.swift +++ b/Sources/ServiceModelGenerate/MockClientDelegate.swift @@ -23,7 +23,7 @@ import ServiceModelEntities A ModelClientDelegate that can be used to generate a mock or throwing test client from a Service Model. */ -public struct MockClientDelegate: ModelClientDelegate { +public struct MockClientDelegate: ModelClientDelegate { public let baseName: String public let isThrowingMock: Bool public let clientType: ClientType @@ -66,8 +66,8 @@ public struct MockClientDelegate: ModelClientDelegate { conformingProtocolNames: ["\(baseName)ClientProtocol", implementationProviderProtocol]) } - public func addTypeDescription(codeGenerator: ServiceModelCodeGenerator, - delegate: ModelClientDelegate, + public func addTypeDescription(codeGenerator: ServiceModelCodeGenerator, + delegate: Self, fileBuilder: FileBuilder, entityType: ClientEntityType) { let functionDetail: String @@ -105,8 +105,8 @@ public struct MockClientDelegate: ModelClientDelegate { """) } - public func addCustomFileHeader(codeGenerator: ServiceModelCodeGenerator, - delegate: ModelClientDelegate, + public func addCustomFileHeader(codeGenerator: ServiceModelCodeGenerator, + delegate: Self, fileBuilder: FileBuilder, fileType: ClientFileType) { fileBuilder.appendLine(""" @@ -130,8 +130,8 @@ public struct MockClientDelegate: ModelClientDelegate { fileBuilder.appendLine("\(variableName): \(name.startingWithUppercase)FunctionType? = nil\(postfix)") } - public func addCommonFunctions(codeGenerator: ServiceModelCodeGenerator, - delegate: ModelClientDelegate, + public func addCommonFunctions(codeGenerator: ServiceModelCodeGenerator, + delegate: Self, fileBuilder: FileBuilder, sortedOperations: [(String, OperationDescription)], entityType: ClientEntityType) { @@ -252,8 +252,8 @@ public struct MockClientDelegate: ModelClientDelegate { """) } - public func addOperationBody(codeGenerator: ServiceModelCodeGenerator, - delegate: ModelClientDelegate, + public func addOperationBody(codeGenerator: ServiceModelCodeGenerator, + delegate: Self, fileBuilder: FileBuilder, invokeType: InvokeType, operationName: String, @@ -278,7 +278,7 @@ public struct MockClientDelegate: ModelClientDelegate { } } - private func delegateMockImplementationCall(codeGenerator: ServiceModelCodeGenerator, + private func delegateMockImplementationCall(codeGenerator: ServiceModelCodeGenerator, functionPrefix: String, functionInfix: String, fileBuilder: FileBuilder, hasInput: Bool, functionOutputType: String?, operationName: String) { @@ -325,7 +325,7 @@ public struct MockClientDelegate: ModelClientDelegate { } } - private func delegateAsyncOnlyMockImplementationCall(codeGenerator: ServiceModelCodeGenerator, + private func delegateAsyncOnlyMockImplementationCall(codeGenerator: ServiceModelCodeGenerator, fileBuilder: FileBuilder, hasInput: Bool, functionOutputType: String?, operationName: String) { let variableName = operationName.upperToLowerCamelCase @@ -350,7 +350,7 @@ public struct MockClientDelegate: ModelClientDelegate { } } - private func addMockClientOperationBody(codeGenerator: ServiceModelCodeGenerator, + private func addMockClientOperationBody(codeGenerator: ServiceModelCodeGenerator, fileBuilder: FileBuilder, hasInput: Bool, functionOutputType: String?, invokeType: InvokeType, protocolTypeName: String, operationName: String) { @@ -412,7 +412,7 @@ public struct MockClientDelegate: ModelClientDelegate { fileBuilder.appendLine("}", preDec: true) } - private func delegateMockThrowingImplementationCall(codeGenerator: ServiceModelCodeGenerator, + private func delegateMockThrowingImplementationCall(codeGenerator: ServiceModelCodeGenerator, functionPrefix: String, functionInfix: String, fileBuilder: FileBuilder, hasInput: Bool, functionOutputType: String?, operationName: String) { @@ -459,7 +459,7 @@ public struct MockClientDelegate: ModelClientDelegate { } } - private func delegateAsyncOnlyMockThrowingImplementationCall(codeGenerator: ServiceModelCodeGenerator, + private func delegateAsyncOnlyMockThrowingImplementationCall(codeGenerator: ServiceModelCodeGenerator, fileBuilder: FileBuilder, hasInput: Bool, functionOutputType: String?, operationName: String) { let variableName = operationName.upperToLowerCamelCase @@ -484,7 +484,7 @@ public struct MockClientDelegate: ModelClientDelegate { } } - private func addThrowingClientOperationBody(codeGenerator: ServiceModelCodeGenerator, + private func addThrowingClientOperationBody(codeGenerator: ServiceModelCodeGenerator, fileBuilder: FileBuilder, hasInput: Bool, functionOutputType: String?, invokeType: InvokeType, operationName: String) { let functionPrefix: String diff --git a/Sources/ServiceModelGenerate/ServiceModelCodeGenerator+addGeneratedFileHeader.swift b/Sources/ServiceModelGenerate/ServiceModelCodeGenerator+addGeneratedFileHeader.swift new file mode 100644 index 0000000..a4e4e3e --- /dev/null +++ b/Sources/ServiceModelGenerate/ServiceModelCodeGenerator+addGeneratedFileHeader.swift @@ -0,0 +1,30 @@ +// Copyright 2019-2022 Amazon.com, Inc. or its affiliates. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"). +// You may not use this file except in compliance with the License. +// A copy of the License is located at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// or in the "license" file accompanying this file. This file is distributed +// on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either +// express or implied. See the License for the specific language governing +// permissions and limitations under the License. +// +// ServiceModelCodeGenerator+addGeneratedFileHeader.swift +// ServiceModelGenerate +// + +import ServiceModelCodeGeneration + +public extension ServiceModelCodeGenerator { + func addGeneratedFileHeader(fileBuilder: FileBuilder) { + fileBuilder.appendLine(""" + // swiftlint:disable superfluous_disable_command + // swiftlint:disable file_length line_length identifier_name type_name vertical_parameter_alignment + // swiftlint:disable type_body_length function_body_length generic_type_name cyclomatic_complexity + // -- Generated Code; do not edit -- + // + """) + } +} diff --git a/Sources/ServiceModelGenerate/ServiceModelCodeGenerator+addRequestInputStructure.swift b/Sources/ServiceModelGenerate/ServiceModelCodeGenerator+addRequestInputStructure.swift index b7bbbac..53ddb44 100644 --- a/Sources/ServiceModelGenerate/ServiceModelCodeGenerator+addRequestInputStructure.swift +++ b/Sources/ServiceModelGenerate/ServiceModelCodeGenerator+addRequestInputStructure.swift @@ -19,8 +19,8 @@ import Foundation import ServiceModelCodeGeneration import ServiceModelEntities -public extension ServiceModelCodeGenerator { - internal func addRequestInputStructure(generationType: ServiceModelCodeGenerator.ClientInputGenerationType, +public extension ServiceModelCodeGenerator where TargetSupportType: ModelTargetSupport & ClientTargetSupport { + internal func addRequestInputStructure(generationType: ClientInputGenerationType, fileBuilder: FileBuilder, name: String, inputTypeName: String, httpRequestInputTypes: HTTPRequestInputTypes) { if case .requestInput = generationType { diff --git a/Sources/ServiceModelGenerate/ServiceModelCodeGenerator+createOutputStructureStubVariable.swift b/Sources/ServiceModelGenerate/ServiceModelCodeGenerator+createOutputStructureStubVariable.swift index b37a9a5..d6e6995 100644 --- a/Sources/ServiceModelGenerate/ServiceModelCodeGenerator+createOutputStructureStubVariable.swift +++ b/Sources/ServiceModelGenerate/ServiceModelCodeGenerator+createOutputStructureStubVariable.swift @@ -19,7 +19,7 @@ import Foundation import ServiceModelCodeGeneration import ServiceModelEntities -internal extension ServiceModelCodeGenerator { +internal extension ServiceModelCodeGenerator where TargetSupportType: ModelTargetSupport { func createOutputStructureStubVariable( type: String, fileBuilder: FileBuilder, @@ -27,7 +27,7 @@ internal extension ServiceModelCodeGenerator { memberLocation: [String: LocationOutput], payloadAsMember: String?) { var outputLines: [String] = [] - let baseName = applicationDescription.baseName + let modelTargetName = self.targetSupport.modelTargetName // if there isn't actually a structure of the type, this is a fatal guard let structureDefinition = model.structureDescriptions[type] else { @@ -40,9 +40,9 @@ internal extension ServiceModelCodeGenerator { } if sortedMembers.isEmpty { - outputLines.append("\(declarationPrefix) \(baseName)Model.\(type)()") + outputLines.append("\(declarationPrefix) \(modelTargetName).\(type)()") } else { - outputLines.append("\(declarationPrefix) \(baseName)Model.\(type)(") + outputLines.append("\(declarationPrefix) \(modelTargetName).\(type)(") } // iterate through each property @@ -84,7 +84,7 @@ internal extension ServiceModelCodeGenerator { // output the declaration if outputLines.isEmpty { - fileBuilder.appendLine("\(declarationPrefix) \(baseName)Model.\(type)()") + fileBuilder.appendLine("\(declarationPrefix) \(modelTargetName).\(type)()") } else { outputLines.forEach { line in fileBuilder.appendLine(line) } } diff --git a/Sources/ServiceModelGenerate/ServiceModelCodeGenerator+createStructureStubVariable.swift b/Sources/ServiceModelGenerate/ServiceModelCodeGenerator+createStructureStubVariable.swift index 4815dc9..6db8a72 100644 --- a/Sources/ServiceModelGenerate/ServiceModelCodeGenerator+createStructureStubVariable.swift +++ b/Sources/ServiceModelGenerate/ServiceModelCodeGenerator+createStructureStubVariable.swift @@ -21,7 +21,7 @@ import ServiceModelEntities let exampleDateString: String = "2013-02-18T17:00:00Z" -internal extension ServiceModelCodeGenerator { +internal extension ServiceModelCodeGenerator where TargetSupportType: ModelTargetSupport { /** Outputs a declaration of a structure with default values for its fields. @@ -39,7 +39,7 @@ internal extension ServiceModelCodeGenerator { fatalOnError: Bool, overrideFieldNameProvider: ((String) -> String?)? = nil) { var outputLines: [String] = [] - let baseName = applicationDescription.baseName + let modelTargetName = self.targetSupport.modelTargetName // if there isn't actually a structure of the type, this is a fatal guard let structureDefinition = model.structureDescriptions[type] else { @@ -70,9 +70,9 @@ internal extension ServiceModelCodeGenerator { } if sortedMembers.isEmpty { - outputLines.append("\(declarationPrefix) \(baseName)Model.\(type)()") + outputLines.append("\(declarationPrefix) \(modelTargetName).\(type)()") } else { - outputLines.append("\(declarationPrefix) \(baseName)Model.\(type)(") + outputLines.append("\(declarationPrefix) \(modelTargetName).\(type)(") } // iterate through each property @@ -85,7 +85,7 @@ internal extension ServiceModelCodeGenerator { // output the declaration if outputLines.isEmpty { - fileBuilder.appendLine("\(declarationPrefix) \(baseName)Model.\(type)()") + fileBuilder.appendLine("\(declarationPrefix) \(modelTargetName).\(type)()") } else { outputLines.forEach { line in fileBuilder.appendLine(line) } } diff --git a/Sources/ServiceModelGenerate/ServiceModelCodeGenerator+generateClient.swift b/Sources/ServiceModelGenerate/ServiceModelCodeGenerator+generateClient.swift index c86c7ab..37decf9 100644 --- a/Sources/ServiceModelGenerate/ServiceModelCodeGenerator+generateClient.swift +++ b/Sources/ServiceModelGenerate/ServiceModelCodeGenerator+generateClient.swift @@ -21,7 +21,7 @@ import ServiceModelEntities internal let asyncAwaitCondition = "#if (os(Linux) && compiler(>=5.5)) || (!os(Linux) && compiler(>=5.5.2)) && canImport(_Concurrency)" -public extension ServiceModelCodeGenerator { +public extension ServiceModelCodeGenerator where TargetSupportType: ModelTargetSupport & ClientTargetSupport { private struct OperationSignature { let input: String let functionInputType: String? @@ -36,9 +36,10 @@ public extension ServiceModelCodeGenerator { - Parameters: - delegate: The delegate to use when generating this client. */ - func generateClient(delegate: ModelClientDelegate, fileType: ClientFileType) { + func generateClient(delegate: DelegateType, fileType: ClientFileType) + where DelegateType.TargetSupportType == TargetSupportType { let fileBuilder = FileBuilder() - let baseName = applicationDescription.baseName + let clientTargetName = self.targetSupport.clientTargetName let fileName: String @@ -133,10 +134,12 @@ public extension ServiceModelCodeGenerator { let fileNameWithExtension = "\(fileName).swift" fileBuilder.write(toFile: fileNameWithExtension, - atFilePath: "\(baseFilePath)/Sources/\(baseName)Client") + atFilePath: "\(baseFilePath)/Sources/\(clientTargetName)") } - private func getTypeName(delegate: ModelClientDelegate, entityType: ClientEntityType, genericType: Bool) -> String { + private func getTypeName(delegate: DelegateType, + entityType: ClientEntityType, genericType: Bool) + -> String where DelegateType.TargetSupportType == TargetSupportType { let typePrefix = genericType ? "Generic" : "" let typePostfix: String switch entityType { @@ -164,8 +167,10 @@ public extension ServiceModelCodeGenerator { } } - private func generateClient(delegate: ModelClientDelegate, entityType: ClientEntityType, - genericType: Bool, fileBuilder: FileBuilder) { + private func generateClient( + delegate: DelegateType, entityType: ClientEntityType, + genericType: Bool, fileBuilder: FileBuilder) + where DelegateType.TargetSupportType == TargetSupportType { let typeName = getTypeName(delegate: delegate, entityType: entityType, genericType: genericType) let typeDecaration: String @@ -263,11 +268,11 @@ public extension ServiceModelCodeGenerator { forTypeAlias: Bool) -> (input: String, functionInputType: String?) { let input: String let functionInputType: String? - let baseName = applicationDescription.baseName + let modelTargetName = self.targetSupport.modelTargetName if let inputType = operationDescription.input { let type = inputType.getNormalizedTypeName(forModel: model) - input = "\(labelPrefix)input: \(baseName)Model.\(type)" + input = "\(labelPrefix)input: \(modelTargetName).\(type)" if !forTypeAlias { fileBuilder.appendEmptyLine() @@ -283,32 +288,34 @@ public extension ServiceModelCodeGenerator { return (input: input, functionInputType: functionInputType) } - private func addOperationOutput(fileBuilder: FileBuilder, - operationDescription: OperationDescription, - delegate: ModelClientDelegate, - labelPrefix: String, operationInvokeType: OperationInvokeType, - forTypeAlias: Bool) -> (output: String, functionOutputType: String?) { + private func addOperationOutput( + fileBuilder: FileBuilder, + operationDescription: OperationDescription, + delegate: DelegateType, + labelPrefix: String, operationInvokeType: OperationInvokeType, + forTypeAlias: Bool) + -> (output: String, functionOutputType: String?) where DelegateType.TargetSupportType == TargetSupportType { let output: String let functionOutputType: String? - let baseName = applicationDescription.baseName + let modelTargetName = self.targetSupport.modelTargetName if let outputType = operationDescription.output { let type = outputType.getNormalizedTypeName(forModel: model) switch operationInvokeType { case .eventLoopFutureAsync: - output = " -> EventLoopFuture<\(baseName)Model.\(type)>" + output = " -> EventLoopFuture<\(modelTargetName).\(type)>" if !forTypeAlias { fileBuilder.appendLine(" - Returns: A future to the \(type) object to be passed back from the caller of this operation.") fileBuilder.appendLine(" Will be validated before being returned to caller.") } case .asyncFunction: - output = " async throws -> \(baseName)Model.\(type)" + output = " async throws -> \(modelTargetName).\(type)" if !forTypeAlias { fileBuilder.appendLine(" - Returns: The \(type) object to be passed back from the caller of this async operation.") fileBuilder.appendLine(" Will be validated before being returned to caller.") } case .syncFunctionForNoAsyncAwaitSupport: - output = " throws -> \(baseName)Model.\(type)" + output = " throws -> \(modelTargetName).\(type)" if !forTypeAlias { fileBuilder.appendLine(" - Returns: The \(type) object to be passed back from the caller of this async operation.") fileBuilder.appendLine(" Will be validated before being returned to caller.") @@ -409,12 +416,14 @@ public extension ServiceModelCodeGenerator { } } - private func addOperationBody(fileBuilder: FileBuilder, name: String, - operationDescription: OperationDescription, - delegate: ModelClientDelegate, - invokeType: InvokeType, forTypeAlias: Bool, - operationSignature: OperationSignature, - entityType: ClientEntityType) { + private func addOperationBody( + fileBuilder: FileBuilder, name: String, + operationDescription: OperationDescription, + delegate: DelegateType, + invokeType: InvokeType, forTypeAlias: Bool, + operationSignature: OperationSignature, + entityType: ClientEntityType) + where DelegateType.TargetSupportType == TargetSupportType { let functionName: String if !forTypeAlias { fileBuilder.appendLine(" */") @@ -475,11 +484,13 @@ public extension ServiceModelCodeGenerator { - forTypeAlias: true if a typealias for the operation should be generated, otherwise the full function */ - internal func addOperation(fileBuilder: FileBuilder, name: String, - operationDescription: OperationDescription, - delegate: ModelClientDelegate, - operationInvokeType: OperationInvokeType, forTypeAlias: Bool, - entityType: ClientEntityType, prefixLine: String? = nil, postfixLine: String? = nil) { + internal func addOperation( + fileBuilder: FileBuilder, name: String, + operationDescription: OperationDescription, + delegate: DelegateType, + operationInvokeType: OperationInvokeType, forTypeAlias: Bool, + entityType: ClientEntityType, prefixLine: String? = nil, postfixLine: String? = nil) + where DelegateType.TargetSupportType == TargetSupportType { // OperationInvokeType.syncFunctionForNoAsyncAwaitSupport is only an internal invoke state // for legacy support so we ignore it other than for where it is necessary let invokeType: InvokeType @@ -544,21 +555,14 @@ public extension ServiceModelCodeGenerator { } } - func addGeneratedFileHeader(fileBuilder: FileBuilder) { - fileBuilder.appendLine(""" - // swiftlint:disable superfluous_disable_command - // swiftlint:disable file_length line_length identifier_name type_name vertical_parameter_alignment - // swiftlint:disable type_body_length function_body_length generic_type_name cyclomatic_complexity - // -- Generated Code; do not edit -- - // - """) - } - - private func addFileHeader(fileBuilder: FileBuilder, - fileName: String, - delegate: ModelClientDelegate, - fileType: ClientFileType) { - let baseName = applicationDescription.baseName + private func addFileHeader( + fileBuilder: FileBuilder, + fileName: String, + delegate: DelegateType, + fileType: ClientFileType) + where DelegateType.TargetSupportType == TargetSupportType { + let modelTargetName = self.targetSupport.modelTargetName + let clientTargetName = self.targetSupport.clientTargetName if let fileHeader = customizations.fileHeader { fileBuilder.appendLine(fileHeader) } @@ -567,11 +571,11 @@ public extension ServiceModelCodeGenerator { fileBuilder.appendLine(""" // \(fileName).swift - // \(baseName)Client + // \(clientTargetName) // import Foundation - import \(baseName)Model + import \(modelTargetName) import SmokeAWSCore import SmokeHTTPClient """) diff --git a/Sources/ServiceModelGenerate/ServiceModelCodeGenerator+generateConversionFunctions.swift b/Sources/ServiceModelGenerate/ServiceModelCodeGenerator+generateConversionFunctions.swift index dbdb15e..86ed315 100644 --- a/Sources/ServiceModelGenerate/ServiceModelCodeGenerator+generateConversionFunctions.swift +++ b/Sources/ServiceModelGenerate/ServiceModelCodeGenerator+generateConversionFunctions.swift @@ -19,12 +19,12 @@ import Foundation import ServiceModelCodeGeneration import ServiceModelEntities -extension ServiceModelCodeGenerator { +extension ServiceModelCodeGenerator where TargetSupportType: ModelTargetSupport { func createArrayConversionFunction(fileBuilder: FileBuilder, name: String, innerType: String) { let typeName = name.getNormalizedTypeName(forModel: model) let innerTypeName = innerType.getNormalizedTypeName(forModel: model) - let baseName = applicationDescription.baseName + let modelTargetName = self.targetSupport.modelTargetName let willConversionFail = willShapeConversionFail(fieldName: innerType, alreadySeenShapes: []) @@ -48,8 +48,8 @@ extension ServiceModelCodeGenerator { fileBuilder.appendLine(""" public extension Array where Element: \(type) { - func as\(baseName)Model\(typeName)()\(failPostfix) -> \(baseName)Model.\(typeName) { - return \(tryPrefix)self.map { \(tryPrefix)$0.as\(baseName)Model\(innerTypeName)() } + func as\(modelTargetName)\(typeName)()\(failPostfix) -> \(modelTargetName).\(typeName) { + return \(tryPrefix)self.map { \(tryPrefix)$0.as\(modelTargetName)\(innerTypeName)() } } } """) @@ -62,8 +62,8 @@ extension ServiceModelCodeGenerator { fileBuilder.appendLine(""" public extension Array where \(whereClause) { - func as\(baseName)Model\(typeName)()\(failPostfix) -> \(baseName)Model.\(typeName) { - return \(tryPrefix)self.map { \(tryPrefix)$0.as\(baseName)Model\(innerTypeName)() } + func as\(modelTargetName)\(typeName)()\(failPostfix) -> \(modelTargetName).\(typeName) { + return \(tryPrefix)self.map { \(tryPrefix)$0.as\(modelTargetName)\(innerTypeName)() } } } """) @@ -71,8 +71,8 @@ extension ServiceModelCodeGenerator { fileBuilder.appendLine(""" public extension Array where Element: CustomStringConvertible { - func as\(baseName)Model\(typeName)()\(failPostfix) -> \(baseName)Model.\(typeName) { - return \(tryPrefix)self.map { \(tryPrefix)$0.as\(baseName)Model\(innerTypeName)() } + func as\(modelTargetName)\(typeName)()\(failPostfix) -> \(modelTargetName).\(typeName) { + return \(tryPrefix)self.map { \(tryPrefix)$0.as\(modelTargetName)\(innerTypeName)() } } } """) @@ -82,7 +82,7 @@ extension ServiceModelCodeGenerator { func createMapConversionFunction(fileBuilder: FileBuilder, name: String, valueType: String) { let typeName = name.getNormalizedTypeName(forModel: model) - let baseName = applicationDescription.baseName + let modelTargetName = self.targetSupport.modelTargetName let willConversionFail = willShapeConversionFail(fieldName: valueType, alreadySeenShapes: []) @@ -106,8 +106,8 @@ extension ServiceModelCodeGenerator { fileBuilder.appendLine(""" public extension Dictionary where Key == String, Value: \(type) { - func as\(baseName)Model\(typeName)()\(failPostfix) -> \(baseName)Model.\(typeName) { - return \(tryPrefix)self.mapValues { \(tryPrefix)$0.as\(baseName)Model\(valueType)() } + func as\(modelTargetName)\(typeName)()\(failPostfix) -> \(modelTargetName).\(typeName) { + return \(tryPrefix)self.mapValues { \(tryPrefix)$0.as\(modelTargetName)\(valueType)() } } } """) @@ -120,8 +120,8 @@ extension ServiceModelCodeGenerator { fileBuilder.appendLine(""" public extension Dictionary where Key == String, \(whereClause) { - func as\(baseName)Model\(typeName)()\(failPostfix) -> \(baseName)Model.\(typeName) { - return \(tryPrefix)self.mapValues { \(tryPrefix)$0.as\(baseName)Model\(valueType)() } + func as\(modelTargetName)\(typeName)()\(failPostfix) -> \(modelTargetName).\(typeName) { + return \(tryPrefix)self.mapValues { \(tryPrefix)$0.as\(modelTargetName)\(valueType)() } } } """) @@ -129,8 +129,8 @@ extension ServiceModelCodeGenerator { fileBuilder.appendLine(""" public extension Dictionary where Value: CustomStringConvertible { - func as\(baseName)Model\(typeName)()\(failPostfix) -> \(baseName)Model.\(typeName) { - return \(tryPrefix)self.mapValues { \(tryPrefix)$0.as\(baseName)Model\(valueType)() } + func as\(modelTargetName)\(typeName)()\(failPostfix) -> \(modelTargetName).\(typeName) { + return \(tryPrefix)self.mapValues { \(tryPrefix)$0.as\(modelTargetName)\(valueType)() } } } """) diff --git a/Sources/ServiceModelGenerate/ServiceModelCodeGenerator+generateDefaultInstances.swift b/Sources/ServiceModelGenerate/ServiceModelCodeGenerator+generateDefaultInstances.swift index 74c54cc..7e28de1 100644 --- a/Sources/ServiceModelGenerate/ServiceModelCodeGenerator+generateDefaultInstances.swift +++ b/Sources/ServiceModelGenerate/ServiceModelCodeGenerator+generateDefaultInstances.swift @@ -24,7 +24,7 @@ public enum DefaultInstancesGenerationType { case json } -public extension ServiceModelCodeGenerator { +public extension ServiceModelCodeGenerator where TargetSupportType: ModelTargetSupport { /** Generate default instances for in a Service Model. @@ -35,6 +35,7 @@ public extension ServiceModelCodeGenerator { let fileBuilder = FileBuilder() let baseName = applicationDescription.baseName + let modelTargetName = self.targetSupport.modelTargetName if let fileHeader = customizations.fileHeader { fileBuilder.appendLine(fileHeader) } @@ -43,7 +44,7 @@ public extension ServiceModelCodeGenerator { fileBuilder.appendLine(""" // \(baseName)ModelDefaultInstances.swift - // \(baseName)Model + // \(modelTargetName) // import Foundation @@ -73,7 +74,7 @@ public extension ServiceModelCodeGenerator { let fileName = "\(baseName)ModelDefaultInstances.swift" let baseFilePath = applicationDescription.baseFilePath - fileBuilder.write(toFile: fileName, atFilePath: "\(baseFilePath)/Sources/\(baseName)Model") + fileBuilder.write(toFile: fileName, atFilePath: "\(baseFilePath)/Sources/\(modelTargetName)") } private func addDefaultValues(_ fileBuilder: FileBuilder) { @@ -100,6 +101,8 @@ public extension ServiceModelCodeGenerator { private func addDefaultStructureInstance(generationType: DefaultInstancesGenerationType, fileBuilder: FileBuilder, name: String, baseName: String, getOverrideFieldName: @escaping (String) -> String?) { + let modelTargetName = self.targetSupport.modelTargetName + switch generationType { case .internalTypes: // create a function that returns the default instance of this structure @@ -109,7 +112,7 @@ public extension ServiceModelCodeGenerator { /** Default instance of the \(name) structure. */ - static let __default: \(baseName)Model.\(name) = { + static let __default: \(modelTargetName).\(name) = { """) fileBuilder.incIndent() fileBuilder.incIndent() diff --git a/Sources/ServiceModelGenerate/ServiceModelCodeGenerator+generateEnumerationDeclaration.swift b/Sources/ServiceModelGenerate/ServiceModelCodeGenerator+generateEnumerationDeclaration.swift index d324b68..3478624 100644 --- a/Sources/ServiceModelGenerate/ServiceModelCodeGenerator+generateEnumerationDeclaration.swift +++ b/Sources/ServiceModelGenerate/ServiceModelCodeGenerator+generateEnumerationDeclaration.swift @@ -19,7 +19,7 @@ import Foundation import ServiceModelCodeGeneration import ServiceModelEntities -extension ServiceModelCodeGenerator { +extension ServiceModelCodeGenerator where TargetSupportType: ModelTargetSupport { /** Generates declaration for an enumeration. @@ -33,7 +33,7 @@ extension ServiceModelCodeGenerator { name: String, valueConstraints: [(name: String, value: String)]) { let typeName = name.getNormalizedTypeName(forModel: model) - let baseName = applicationDescription.baseName + let modelTargetName = self.targetSupport.modelTargetName fileBuilder.appendEmptyLine() fileBuilder.appendLine("/**") @@ -85,12 +85,12 @@ extension ServiceModelCodeGenerator { fileBuilder.appendEmptyLine() fileBuilder.appendLine(""" public extension CustomStringConvertible { - func as\(baseName)Model\(typeName)() throws -> \(baseName)Model.\(typeName) { + func as\(modelTargetName)\(typeName)() throws -> \(modelTargetName).\(typeName) { let description = self.description guard let result = \(typeName)(rawValue: description) else { throw \(validationErrorType).validationError(reason: "Unable to convert value '" - + description + "' to a \(baseName)Model.\(name) value.") + + description + "' to a \(modelTargetName).\(name) value.") } return result diff --git a/Sources/ServiceModelGenerate/ServiceModelCodeGenerator+generateModelErrors.swift b/Sources/ServiceModelGenerate/ServiceModelCodeGenerator+generateModelErrors.swift index d5ff3d7..722111e 100644 --- a/Sources/ServiceModelGenerate/ServiceModelCodeGenerator+generateModelErrors.swift +++ b/Sources/ServiceModelGenerate/ServiceModelCodeGenerator+generateModelErrors.swift @@ -19,7 +19,7 @@ import Foundation import ServiceModelCodeGeneration import ServiceModelEntities -public extension ServiceModelCodeGenerator { +public extension ServiceModelCodeGenerator where TargetSupportType: ModelTargetSupport { /** Generate the errors specified in the Model. @@ -30,6 +30,7 @@ public extension ServiceModelCodeGenerator { let fileBuilder = FileBuilder() let baseName = applicationDescription.baseName + let modelTargetName = self.targetSupport.modelTargetName if let fileHeader = customizations.fileHeader { fileBuilder.appendLine(fileHeader) } @@ -38,7 +39,7 @@ public extension ServiceModelCodeGenerator { fileBuilder.appendLine(""" // \(baseName)ModelErrors.swift - // \(baseName)Model + // \(modelTargetName) // import Foundation @@ -89,7 +90,7 @@ public extension ServiceModelCodeGenerator { } let fileName = "\(baseName)ModelErrors.swift" - fileBuilder.write(toFile: fileName, atFilePath: "\(applicationDescription.baseFilePath)/Sources/\(baseName)Model") + fileBuilder.write(toFile: fileName, atFilePath: "\(applicationDescription.baseFilePath)/Sources/\(modelTargetName)") } func getSortedErrors(allErrorTypes: Set) -> [ErrorType] { diff --git a/Sources/ServiceModelGenerate/ServiceModelCodeGenerator+generateModelInvocationsReporting.swift b/Sources/ServiceModelGenerate/ServiceModelCodeGenerator+generateModelInvocationsReporting.swift index f7074d7..c831a74 100644 --- a/Sources/ServiceModelGenerate/ServiceModelCodeGenerator+generateModelInvocationsReporting.swift +++ b/Sources/ServiceModelGenerate/ServiceModelCodeGenerator+generateModelInvocationsReporting.swift @@ -19,7 +19,7 @@ import Foundation import ServiceModelCodeGeneration import ServiceModelEntities -public extension ServiceModelCodeGenerator { +public extension ServiceModelCodeGenerator where TargetSupportType: ModelTargetSupport & ClientTargetSupport { /** Generate an operation enumeration for the model. */ @@ -27,6 +27,8 @@ public extension ServiceModelCodeGenerator { let fileBuilder = FileBuilder() let baseName = applicationDescription.baseName + let modelTargetName = self.targetSupport.modelTargetName + let clientTargetName = self.targetSupport.clientTargetName if let fileHeader = customizations.fileHeader { fileBuilder.appendLine(fileHeader) } @@ -35,13 +37,13 @@ public extension ServiceModelCodeGenerator { fileBuilder.appendLine(""" // \(baseName)InvocationsReporting.swift - // \(baseName)Client + // \(clientTargetName) // import Foundation import SmokeHTTPClient import SmokeAWSHttp - import \(baseName)Model + import \(modelTargetName) """) if case let .external(libraryImport: libraryImport, _) = customizations.validationErrorDeclaration { @@ -57,7 +59,7 @@ public extension ServiceModelCodeGenerator { fileBuilder.appendLine(""" /** - Invocations reporting for the \(baseName)Model. + Invocations reporting for the \(modelTargetName). */ public struct \(baseName)InvocationsReporting { """) @@ -75,7 +77,7 @@ public extension ServiceModelCodeGenerator { let fileName = "\(baseName)InvocationsReporting.swift" let baseFilePath = applicationDescription.baseFilePath - fileBuilder.write(toFile: fileName, atFilePath: "\(baseFilePath)/Sources/\(baseName)Client") + fileBuilder.write(toFile: fileName, atFilePath: "\(baseFilePath)/Sources/\(clientTargetName)") } private func addOperationReportingParameters(fileBuilder: FileBuilder, baseName: String, diff --git a/Sources/ServiceModelGenerate/ServiceModelCodeGenerator+generateModelOperationClientInput.swift b/Sources/ServiceModelGenerate/ServiceModelCodeGenerator+generateModelOperationClientInput.swift index 1f50b34..06ad951 100644 --- a/Sources/ServiceModelGenerate/ServiceModelCodeGenerator+generateModelOperationClientInput.swift +++ b/Sources/ServiceModelGenerate/ServiceModelCodeGenerator+generateModelOperationClientInput.swift @@ -19,7 +19,7 @@ import Foundation import ServiceModelCodeGeneration import ServiceModelEntities -public extension ServiceModelCodeGenerator { +public extension ServiceModelCodeGenerator where TargetSupportType: ModelTargetSupport & ClientTargetSupport { internal struct HTTPRequestInputTypes { let queryTypeName: String let queryTypeConversion: String @@ -37,6 +37,8 @@ public extension ServiceModelCodeGenerator { */ func generateModelOperationClientInput() { let baseName = applicationDescription.baseName + let modelTargetName = self.targetSupport.modelTargetName + let clientTargetName = self.targetSupport.clientTargetName let fileBuilder = FileBuilder() @@ -48,12 +50,12 @@ public extension ServiceModelCodeGenerator { fileBuilder.appendLine(""" // \(baseName)OperationsClientInput.swift - // \(baseName)Client + // \(clientTargetName) // import Foundation import SmokeHTTPClient - import \(baseName)Model + import \(modelTargetName) """) if case let .external(libraryImport: libraryImport, _) = customizations.validationErrorDeclaration { @@ -71,7 +73,7 @@ public extension ServiceModelCodeGenerator { let fileName = "\(baseName)OperationsClientInput.swift" let baseFilePath = applicationDescription.baseFilePath - fileBuilder.write(toFile: fileName, atFilePath: "\(baseFilePath)/Sources/\(baseName)Client") + fileBuilder.write(toFile: fileName, atFilePath: "\(baseFilePath)/Sources/\(clientTargetName)") } private func addPathOperationHTTPRequestInput(pathMembers: [String: Member], @@ -82,7 +84,7 @@ public extension ServiceModelCodeGenerator { fileBuilder: FileBuilder) -> (pathTypeName: String, pathTypeConversion: String) { let pathTypeName: String let pathTypeConversion: String - let baseName = applicationDescription.baseName + let modelTargetName = self.targetSupport.modelTargetName if !pathMembers.isEmpty { pathTypeName = "\(operationPrefix)Path" let structureDefinition = StructureDescription( @@ -103,7 +105,7 @@ public extension ServiceModelCodeGenerator { fileBuilder: fileBuilder) } - pathTypeConversion = "encodable.as\(baseName)Model\(operationPrefix)Path()" + pathTypeConversion = "encodable.as\(modelTargetName)\(operationPrefix)Path()" } else { pathTypeName = "String" pathTypeConversion = "nil" @@ -120,7 +122,7 @@ public extension ServiceModelCodeGenerator { fileBuilder: FileBuilder) -> (queryTypeName: String, queryTypeConversion: String) { let queryTypeName: String let queryTypeConversion: String - let baseName = applicationDescription.baseName + let modelTargetName = self.targetSupport.modelTargetName if !queryMembers.isEmpty { queryTypeName = "\(operationPrefix)Query" let structureDefinition = StructureDescription( @@ -141,7 +143,7 @@ public extension ServiceModelCodeGenerator { fileBuilder: fileBuilder) } - queryTypeConversion = "encodable.as\(baseName)Model\(operationPrefix)Query()" + queryTypeConversion = "encodable.as\(modelTargetName)\(operationPrefix)Query()" } else { queryTypeName = "String" queryTypeConversion = "nil" @@ -158,7 +160,7 @@ public extension ServiceModelCodeGenerator { fileBuilder: FileBuilder) -> (bodyTypeName: String, bodyTypeConversion: String) { let bodyTypeName: String let bodyTypeConversion: String - let baseName = applicationDescription.baseName + let modelTargetName = self.targetSupport.modelTargetName if !bodyMembers.isEmpty { bodyTypeName = "\(operationPrefix)Body" let structureDefinition = StructureDescription( @@ -179,7 +181,7 @@ public extension ServiceModelCodeGenerator { fileBuilder: fileBuilder) } - bodyTypeConversion = "encodable.as\(baseName)Model\(operationPrefix)Body()" + bodyTypeConversion = "encodable.as\(modelTargetName)\(operationPrefix)Body()" } else { bodyTypeName = "String" bodyTypeConversion = "nil" @@ -197,7 +199,7 @@ public extension ServiceModelCodeGenerator { -> (additionalHeadersTypeName: String, additionalHeadersTypeConversion: String) { let additionalHeadersTypeName: String let additionalHeadersTypeConversion: String - let baseName = applicationDescription.baseName + let modelTargetName = self.targetSupport.modelTargetName if !additionalHeadersMembers.isEmpty { additionalHeadersTypeName = "\(operationPrefix)AdditionalHeaders" let structureDefinition = StructureDescription( @@ -218,7 +220,7 @@ public extension ServiceModelCodeGenerator { fileBuilder: fileBuilder) } - additionalHeadersTypeConversion = "encodable.as\(baseName)Model\(operationPrefix)AdditionalHeaders()" + additionalHeadersTypeConversion = "encodable.as\(modelTargetName)\(operationPrefix)AdditionalHeaders()" } else { additionalHeadersTypeName = "String" additionalHeadersTypeConversion = "nil" diff --git a/Sources/ServiceModelGenerate/ServiceModelCodeGenerator+generateModelOperationClientOutput.swift b/Sources/ServiceModelGenerate/ServiceModelCodeGenerator+generateModelOperationClientOutput.swift index 46e7c2b..367fc9f 100644 --- a/Sources/ServiceModelGenerate/ServiceModelCodeGenerator+generateModelOperationClientOutput.swift +++ b/Sources/ServiceModelGenerate/ServiceModelCodeGenerator+generateModelOperationClientOutput.swift @@ -19,7 +19,7 @@ import Foundation import ServiceModelCodeGeneration import ServiceModelEntities -public extension ServiceModelCodeGenerator { +public extension ServiceModelCodeGenerator where TargetSupportType: ModelTargetSupport & ClientTargetSupport { private struct HTTPResponseOutputTypes { let bodyTypeName: String let headersTypeName: String @@ -32,6 +32,8 @@ public extension ServiceModelCodeGenerator { */ func generateModelOperationClientOutput() { let baseName = applicationDescription.baseName + let modelTargetName = self.targetSupport.modelTargetName + let clientTargetName = self.targetSupport.clientTargetName let fileBuilder = FileBuilder() @@ -43,12 +45,12 @@ public extension ServiceModelCodeGenerator { fileBuilder.appendLine(""" // \(baseName)OperationsClientOutput.swift - // \(baseName)Client + // \(clientTargetName) // import Foundation import SmokeHTTPClient - import \(baseName)Model + import \(modelTargetName) """) if case let .external(libraryImport: libraryImport, _) = customizations.validationErrorDeclaration { @@ -68,7 +70,7 @@ public extension ServiceModelCodeGenerator { let fileName = "\(baseName)OperationsClientOutput.swift" let baseFilePath = applicationDescription.baseFilePath - fileBuilder.write(toFile: fileName, atFilePath: "\(baseFilePath)/Sources/\(baseName)Client") + fileBuilder.write(toFile: fileName, atFilePath: "\(baseFilePath)/Sources/\(clientTargetName)") } private func addBodyOperationHTTPResponseOutput(bodyMembers: [String: Member], diff --git a/Sources/ServiceModelGenerate/ServiceModelCodeGenerator+generateModelOperationsEnum.swift b/Sources/ServiceModelGenerate/ServiceModelCodeGenerator+generateModelOperationsEnum.swift index a2f9c6c..3412457 100644 --- a/Sources/ServiceModelGenerate/ServiceModelCodeGenerator+generateModelOperationsEnum.swift +++ b/Sources/ServiceModelGenerate/ServiceModelCodeGenerator+generateModelOperationsEnum.swift @@ -19,7 +19,7 @@ import Foundation import ServiceModelCodeGeneration import ServiceModelEntities -public extension ServiceModelCodeGenerator { +public extension ServiceModelCodeGenerator where TargetSupportType: ModelTargetSupport & ClientTargetSupport { /** Generate an operation enumeration for the model. */ @@ -27,6 +27,7 @@ public extension ServiceModelCodeGenerator { let fileBuilder = FileBuilder() let baseName = applicationDescription.baseName + let modelTargetName = self.targetSupport.modelTargetName if let fileHeader = customizations.fileHeader { fileBuilder.appendLine(fileHeader) } @@ -35,7 +36,7 @@ public extension ServiceModelCodeGenerator { fileBuilder.appendLine(""" // \(baseName)ModelOperations.swift - // \(baseName)Model + // \(modelTargetName) // import Foundation @@ -89,7 +90,7 @@ public extension ServiceModelCodeGenerator { let fileName = "\(baseName)ModelOperations.swift" let baseFilePath = applicationDescription.baseFilePath - fileBuilder.write(toFile: fileName, atFilePath: "\(baseFilePath)/Sources/\(baseName)Model") + fileBuilder.write(toFile: fileName, atFilePath: "\(baseFilePath)/Sources/\(modelTargetName)") } private func addOperationCases(sortedOperations: [(key: String, value: OperationDescription)], fileBuilder: FileBuilder) { diff --git a/Sources/ServiceModelGenerate/ServiceModelCodeGenerator+generateModelOperationsReporting.swift b/Sources/ServiceModelGenerate/ServiceModelCodeGenerator+generateModelOperationsReporting.swift index a3d5536..39b9c7a 100644 --- a/Sources/ServiceModelGenerate/ServiceModelCodeGenerator+generateModelOperationsReporting.swift +++ b/Sources/ServiceModelGenerate/ServiceModelCodeGenerator+generateModelOperationsReporting.swift @@ -19,7 +19,7 @@ import Foundation import ServiceModelCodeGeneration import ServiceModelEntities -public extension ServiceModelCodeGenerator { +public extension ServiceModelCodeGenerator where TargetSupportType: ModelTargetSupport & ClientTargetSupport { /** Generate an operation enumeration for the model. */ @@ -27,6 +27,8 @@ public extension ServiceModelCodeGenerator { let fileBuilder = FileBuilder() let baseName = applicationDescription.baseName + let modelTargetName = self.targetSupport.modelTargetName + let clientTargetName = self.targetSupport.clientTargetName if let fileHeader = customizations.fileHeader { fileBuilder.appendLine(fileHeader) } @@ -35,12 +37,12 @@ public extension ServiceModelCodeGenerator { fileBuilder.appendLine(""" // \(baseName)OperationsReporting.swift - // \(baseName)Client + // \(clientTargetName) // import Foundation import SmokeAWSCore - import \(baseName)Model + import \(modelTargetName) """) if case let .external(libraryImport: libraryImport, _) = customizations.validationErrorDeclaration { @@ -50,7 +52,7 @@ public extension ServiceModelCodeGenerator { fileBuilder.appendLine(""" /** - Operation reporting for the \(baseName)Model. + Operation reporting for the \(modelTargetName). */ public struct \(baseName)OperationsReporting { """) @@ -68,7 +70,7 @@ public extension ServiceModelCodeGenerator { let fileName = "\(baseName)OperationsReporting.swift" let baseFilePath = applicationDescription.baseFilePath - fileBuilder.write(toFile: fileName, atFilePath: "\(baseFilePath)/Sources/\(baseName)Client") + fileBuilder.write(toFile: fileName, atFilePath: "\(baseFilePath)/Sources/\(clientTargetName)") } private func addOperationReportingParameters(fileBuilder: FileBuilder, baseName: String, diff --git a/Sources/ServiceModelGenerate/ServiceModelCodeGenerator+generateModelStructures.swift b/Sources/ServiceModelGenerate/ServiceModelCodeGenerator+generateModelStructures.swift index 590c70b..732d0ca 100644 --- a/Sources/ServiceModelGenerate/ServiceModelCodeGenerator+generateModelStructures.swift +++ b/Sources/ServiceModelGenerate/ServiceModelCodeGenerator+generateModelStructures.swift @@ -19,8 +19,8 @@ import Foundation import ServiceModelCodeGeneration import ServiceModelEntities -public extension ServiceModelCodeGenerator { - +public extension ServiceModelCodeGenerator where TargetSupportType: ModelTargetSupport { + struct StructureElements { var codingKeyLines: [String] = [] var constructorSignatureLines: [String] = [] @@ -41,6 +41,7 @@ public extension ServiceModelCodeGenerator { let fileBuilder = FileBuilder() let baseName = applicationDescription.baseName + let modelTargetName = self.targetSupport.modelTargetName if let fileHeader = customizations.fileHeader { fileBuilder.appendLine(fileHeader) } @@ -49,7 +50,7 @@ public extension ServiceModelCodeGenerator { fileBuilder.appendLine(""" // \(baseName)ModelStructures.swift - // \(baseName)Model + // \(modelTargetName) // import Foundation @@ -80,7 +81,7 @@ public extension ServiceModelCodeGenerator { let fileName = "\(baseName)ModelStructures.swift" let baseFilePath = applicationDescription.baseFilePath - fileBuilder.write(toFile: fileName, atFilePath: "\(baseFilePath)/Sources/\(baseName)Model") + fileBuilder.write(toFile: fileName, atFilePath: "\(baseFilePath)/Sources/\(modelTargetName)") } private func addCodingKeyLines(name: String, modelName: String?, diff --git a/Sources/ServiceModelGenerate/ServiceModelCodeGenerator+generateModelTypes.swift b/Sources/ServiceModelGenerate/ServiceModelCodeGenerator+generateModelTypes.swift index 6f4161a..cf3e741 100644 --- a/Sources/ServiceModelGenerate/ServiceModelCodeGenerator+generateModelTypes.swift +++ b/Sources/ServiceModelGenerate/ServiceModelCodeGenerator+generateModelTypes.swift @@ -19,7 +19,7 @@ import Foundation import ServiceModelCodeGeneration import ServiceModelEntities -public extension ServiceModelCodeGenerator { +public extension ServiceModelCodeGenerator where TargetSupportType: ModelTargetSupport { /** Generate the declarations for structures specified in a Service Model. */ @@ -27,6 +27,7 @@ public extension ServiceModelCodeGenerator { let fileBuilder = FileBuilder() let baseName = applicationDescription.baseName + let modelTargetName = self.targetSupport.modelTargetName if let fileHeader = customizations.fileHeader { fileBuilder.appendLine(fileHeader) } @@ -35,7 +36,7 @@ public extension ServiceModelCodeGenerator { fileBuilder.appendLine(""" // \(baseName)ModelTypes.swift - // \(baseName)Model + // \(modelTargetName) // import Foundation @@ -56,7 +57,7 @@ public extension ServiceModelCodeGenerator { let fileName = "\(baseName)ModelTypes.swift" let baseFilePath = applicationDescription.baseFilePath - fileBuilder.write(toFile: fileName, atFilePath: "\(baseFilePath)/Sources/\(baseName)Model") + fileBuilder.write(toFile: fileName, atFilePath: "\(baseFilePath)/Sources/\(modelTargetName)") } private func addStringFieldValidation(name: String, fieldValueConstraints: [(name: String, value: String)], regexConstraint: String?, diff --git a/Sources/ServiceModelGenerate/ServiceModelCodeGenerator+shapeConversion.swift b/Sources/ServiceModelGenerate/ServiceModelCodeGenerator+shapeConversion.swift index bba713b..1d8f187 100644 --- a/Sources/ServiceModelGenerate/ServiceModelCodeGenerator+shapeConversion.swift +++ b/Sources/ServiceModelGenerate/ServiceModelCodeGenerator+shapeConversion.swift @@ -19,12 +19,12 @@ import Foundation import ServiceModelCodeGeneration import ServiceModelEntities -internal extension ServiceModelCodeGenerator { +internal extension ServiceModelCodeGenerator where TargetSupportType: ModelTargetSupport { func createConversionFunction(originalTypeName: String, derivedTypeName: String, members: [String: Member], fileBuilder: FileBuilder) { - let baseName = applicationDescription.baseName + let modelTargetName = self.targetSupport.modelTargetName let postfix: String if members.isEmpty { postfix = ")" @@ -34,7 +34,7 @@ internal extension ServiceModelCodeGenerator { fileBuilder.appendLine(""" public extension \(originalTypeName) { - func as\(baseName)Model\(derivedTypeName)() -> \(derivedTypeName) { + func as\(modelTargetName)\(derivedTypeName)() -> \(derivedTypeName) { return \(derivedTypeName)(\(postfix) """) @@ -74,22 +74,23 @@ internal extension ServiceModelCodeGenerator { let fieldShape: String if !valueConstraints.isEmpty { let capitalizedVariableName = variableName.lowerToUpperCamelCase + let modelTargetName = self.targetSupport.modelTargetName if isRequired { setup = """ - guard let converted\(capitalizedVariableName) = \(baseName)Model.\(fieldName)(rawValue: \(variableName).description) else { + guard let converted\(capitalizedVariableName) = \(modelTargetName).\(fieldName)(rawValue: \(variableName).description) else { throw \(validationErrorType).validationError(reason: "Unable to convert value '" - + \(variableName).description + "' of field '\(variableName)' to a \(baseName)Model.\(fieldName) value.") + + \(variableName).description + "' of field '\(variableName)' to a \(modelTargetName).\(fieldName) value.") } """ } else { setup = """ - let converted\(capitalizedVariableName): \(baseName)Model.\(fieldName)? + let converted\(capitalizedVariableName): \(modelTargetName).\(fieldName)? if let description = \(variableName)?.description { - if let new\(fieldName) = \(baseName)Model.\(fieldName)(rawValue: description) { + if let new\(fieldName) = \(modelTargetName).\(fieldName)(rawValue: description) { converted\(capitalizedVariableName) = new\(fieldName) } else { throw \(validationErrorType).validationError(reason: "Unable to convert value '" - + description + "' of field '\(variableName)' to a \(baseName)Model.\(fieldName) value.") + + description + "' of field '\(variableName)' to a \(modelTargetName).\(fieldName) value.") } } else { converted\(capitalizedVariableName) = nil @@ -113,7 +114,7 @@ internal extension ServiceModelCodeGenerator { let optionalInfix = isRequired ? "" : "?" let typeName = type.getNormalizedTypeName(forModel: model) - let baseName = applicationDescription.baseName + let modelTargetName = self.targetSupport.modelTargetName let conversionDetails = getShapeToInstanceConversion(fieldType: type, variableName: "entry", @@ -125,7 +126,7 @@ internal extension ServiceModelCodeGenerator { if conversionDetails.conversion == "entry" { setupBuilder = "let converted\(capitalizedVariableName) = \(variableName)" } else { - let fieldType = "[\(baseName)Model.\(typeName)]\(optionalInfix)" + let fieldType = "[\(modelTargetName).\(typeName)]\(optionalInfix)" setupBuilder = "let converted\(capitalizedVariableName): \(fieldType) = \(failPostfix)\(variableName)\(optionalInfix).map { entry in\n" if let setup = conversionDetails.setup { @@ -149,17 +150,17 @@ internal extension ServiceModelCodeGenerator { let keyTypeName = keyType.getNormalizedTypeName(forModel: model) let valueTypeName = valueType.getNormalizedTypeName(forModel: model) - let baseName = applicationDescription.baseName + let modelTargetName = self.targetSupport.modelTargetName let conversionDetails = getShapeToInstanceConversion(fieldType: valueType, variableName: "entry", isRequired: true) - let fullKeyTypeName = keyTypeName.isBuiltinType ? keyTypeName : "\(baseName)Model.\(keyTypeName)" + let fullKeyTypeName = keyTypeName.isBuiltinType ? keyTypeName : "\(modelTargetName).\(keyTypeName)" // if there is actually conversion on each element if conversionDetails.conversion != "entry" && !valueTypeName.isBuiltinType { - let fullValueTypeName = "\(baseName)Model.\(valueTypeName)" + let fullValueTypeName = "\(modelTargetName).\(valueTypeName)" let capitalizedVariableName = variableName.lowerToUpperCamelCase let fieldType = "[\(fullKeyTypeName): \(fullValueTypeName)]\(optionalInfix)" @@ -186,6 +187,7 @@ internal extension ServiceModelCodeGenerator { -> (conversion: String, setup: String?) { let baseName = applicationDescription.baseName + let modelTargetName = self.targetSupport.modelTargetName let fieldName = fieldType.getNormalizedTypeName(forModel: model) let fieldShape: String var setup: String? @@ -209,7 +211,7 @@ internal extension ServiceModelCodeGenerator { let willConversionFail = willShapeConversionFail(fieldName: fieldName, alreadySeenShapes: []) let failPostfix = willConversionFail ? "try " : "" - fieldShape = "\(failPostfix)\(variableName)\(optionalInfix).as\(baseName)Model\(fieldName)()" + fieldShape = "\(failPostfix)\(variableName)\(optionalInfix).as\(modelTargetName)\(fieldName)()" } return (fieldShape, setup) diff --git a/Sources/ServiceModelGenerate/ServiceModelCodeGenerator+shapeProtocol.swift b/Sources/ServiceModelGenerate/ServiceModelCodeGenerator+shapeProtocol.swift index bce01a8..0a50c94 100644 --- a/Sources/ServiceModelGenerate/ServiceModelCodeGenerator+shapeProtocol.swift +++ b/Sources/ServiceModelGenerate/ServiceModelCodeGenerator+shapeProtocol.swift @@ -19,10 +19,10 @@ import Foundation import ServiceModelCodeGeneration import ServiceModelEntities -internal extension ServiceModelCodeGenerator { +internal extension ServiceModelCodeGenerator where TargetSupportType: ModelTargetSupport { func addShapeProtocol(name: String, fileBuilder: FileBuilder, structureElements: StructureElements) { - let baseName = applicationDescription.baseName + let modelTargetName = self.targetSupport.modelTargetName // add conformance to Equatable fileBuilder.appendLine(""" @@ -51,14 +51,14 @@ internal extension ServiceModelCodeGenerator { fileBuilder.appendLine(""" - func as\(baseName)Model\(name)()\(failPostix) -> \(baseName)Model.\(name) + func as\(modelTargetName)\(name)()\(failPostix) -> \(modelTargetName).\(name) } """) } func addShapeDefaultFunctions(name: String, fileBuilder: FileBuilder, structureElements: StructureElements) { - let baseName = applicationDescription.baseName + let modelTargetName = self.targetSupport.modelTargetName let willConversionFail = willShapeConversionFail(fieldName: name, alreadySeenShapes: []) let failPostix = willConversionFail ? " throws" : "" @@ -67,7 +67,7 @@ internal extension ServiceModelCodeGenerator { public extension \(name)Shape { - func as\(baseName)Model\(name)()\(failPostix) -> \(baseName)Model.\(name) { + func as\(modelTargetName)\(name)()\(failPostix) -> \(modelTargetName).\(name) { if let modelInstance = self as? \(name) { // don't need to convert, already can be serialized return modelInstance diff --git a/Sources/ServiceModelGenerate/ServiceModelCodeGenerator+validationFunctions.swift b/Sources/ServiceModelGenerate/ServiceModelCodeGenerator+validationFunctions.swift index be8cb36..48ed4e7 100644 --- a/Sources/ServiceModelGenerate/ServiceModelCodeGenerator+validationFunctions.swift +++ b/Sources/ServiceModelGenerate/ServiceModelCodeGenerator+validationFunctions.swift @@ -19,7 +19,7 @@ import Foundation import ServiceModelCodeGeneration import ServiceModelEntities -extension ServiceModelCodeGenerator { +extension ServiceModelCodeGenerator where TargetSupportType: ModelTargetSupport { /** Generates validation for a field with length constraints. @@ -94,19 +94,19 @@ extension ServiceModelCodeGenerator { let typeName: String let extensionName: String let extensionDeclaration: String - let baseName = applicationDescription.baseName + let modelTargetName = self.targetSupport.modelTargetName if let isListWithInnerType = isListWithInnerType { typeName = isListWithInnerType.getNormalizedTypeName(forModel: model) extensionName = name.getNormalizedTypeName(forModel: model) if typeName.isBuiltinType { extensionDeclaration = "Array where Element == \(typeName)" } else { - extensionDeclaration = "Array where Element == \(baseName)Model.\(typeName)" + extensionDeclaration = "Array where Element == \(modelTargetName).\(typeName)" } } else { typeName = name.getNormalizedTypeName(forModel: model) extensionName = typeName - extensionDeclaration = "\(baseName)Model.\(typeName)" + extensionDeclaration = "\(modelTargetName).\(typeName)" } // if there are constraints diff --git a/Sources/ServiceModelGenerate/ServiceModelGenerate.swift b/Sources/ServiceModelGenerate/ServiceModelGenerate.swift index 9131681..6e4e355 100644 --- a/Sources/ServiceModelGenerate/ServiceModelGenerate.swift +++ b/Sources/ServiceModelGenerate/ServiceModelGenerate.swift @@ -73,12 +73,13 @@ public struct ServiceModelGenerate { - generatorFunction: a function that will be provided a code generator and an instantiated ServiceModel which can be used to generate any code that is required. */ - public static func generateFromModel( + public static func generateFromModel( modelFilePath: String, customizations: CodeGenerationCustomizations, applicationDescription: ApplicationDescription, modelOverride: ModelOverride?, - generatorFunction: (ServiceModelCodeGenerator, ModelType) throws -> ()) throws + targetSupport: TargetSupportType, + generatorFunction: (ServiceModelCodeGenerator, ModelType) throws -> ()) throws -> ModelType { let (data, modelFormat) = getModelDataForFilePath(modelFilePath: modelFilePath) @@ -88,13 +89,29 @@ public struct ServiceModelGenerate { model: model, applicationDescription: applicationDescription, customizations: customizations, - modelOverride: modelOverride) + modelOverride: modelOverride, + targetSupport: targetSupport) try generatorFunction(codeGenerator, model) return model } + public static func generateFromModel( + modelFilePath: String, + customizations: CodeGenerationCustomizations, + applicationDescription: ApplicationDescription, + modelOverride: ModelOverride?, + generatorFunction: (ServiceModelCodeGenerator, ModelType) throws -> ()) throws + -> ModelType { + return try generateFromModel(modelFilePath: modelFilePath, + customizations: customizations, + applicationDescription: applicationDescription, + modelOverride: modelOverride, + targetSupport: applicationDescription.defaultTargetSupport, + generatorFunction: generatorFunction) + } + /** Helper function to initialize code generation from the path to a service model. @@ -106,12 +123,13 @@ public struct ServiceModelGenerate { - generatorFunction: a function that will be provided a code generator and an instantiated ServiceModel which can be used to generate any code that is required. */ - public static func generateFromModel( + public static func generateFromModel( modelFilePaths: [String], customizations: CodeGenerationCustomizations, applicationDescription: ApplicationDescription, modelOverride: ModelOverride?, - generatorFunction: (ServiceModelCodeGenerator, ModelType) throws -> ()) throws + targetSupport: TargetSupportType, + generatorFunction: (ServiceModelCodeGenerator, ModelType) throws -> ()) throws -> ModelType { var modelFormat: ModelFormat? let dataList: [Data] = modelFilePaths.map { modelFilePath in @@ -135,13 +153,29 @@ public struct ServiceModelGenerate { model: model, applicationDescription: applicationDescription, customizations: customizations, - modelOverride: modelOverride) + modelOverride: modelOverride, + targetSupport: targetSupport) try generatorFunction(codeGenerator, model) return model } + public static func generateFromModel( + modelFilePaths: [String], + customizations: CodeGenerationCustomizations, + applicationDescription: ApplicationDescription, + modelOverride: ModelOverride?, + generatorFunction: (ServiceModelCodeGenerator, ModelType) throws -> ()) throws + -> ModelType { + return try generateFromModel(modelFilePaths: modelFilePaths, + customizations: customizations, + applicationDescription: applicationDescription, + modelOverride: modelOverride, + targetSupport: applicationDescription.defaultTargetSupport, + generatorFunction: generatorFunction) + } + /** Helper function to initialize code generation from the path to a service model. @@ -154,13 +188,14 @@ public struct ServiceModelGenerate { - generatorFunction: a function that will be provided a code generator and an instantiated ServiceModel which can be used to generate any code that is required. */ - public static func generateFromModel( + public static func generateFromModel( modelDirectoryPath: String, fileExtension: String, customizations: CodeGenerationCustomizations, applicationDescription: ApplicationDescription, modelOverride: ModelOverride?, - generatorFunction: (ServiceModelCodeGenerator, ModelType) throws -> ()) throws + targetSupport: TargetSupportType, + generatorFunction: (ServiceModelCodeGenerator, ModelType) throws -> ()) throws -> ModelType { let dataList = try getDataListForModelFiles(atPath: modelDirectoryPath, fileExtension: fileExtension) @@ -172,13 +207,31 @@ public struct ServiceModelGenerate { model: model, applicationDescription: applicationDescription, customizations: customizations, - modelOverride: modelOverride) + modelOverride: modelOverride, + targetSupport: targetSupport) try generatorFunction(codeGenerator, model) return model } + public static func generateFromModel( + modelDirectoryPath: String, + fileExtension: String, + customizations: CodeGenerationCustomizations, + applicationDescription: ApplicationDescription, + modelOverride: ModelOverride?, + generatorFunction: (ServiceModelCodeGenerator, ModelType) throws -> ()) throws + -> ModelType { + return try generateFromModel(modelDirectoryPath: modelDirectoryPath, + fileExtension: fileExtension, + customizations: customizations, + applicationDescription: applicationDescription, + modelOverride: modelOverride, + targetSupport: applicationDescription.defaultTargetSupport, + generatorFunction: generatorFunction) + } + /** Helper function to initialize code generation from the paths to service models. @@ -191,13 +244,14 @@ public struct ServiceModelGenerate { - generatorFunction: a function that will be provided a code generator and an instantiated ServiceModel which can be used to generate any code that is required. */ - public static func generateFromModel( + public static func generateFromModel( modelDirectoryPaths: [String], fileExtension: String, customizations: CodeGenerationCustomizations, applicationDescription: ApplicationDescription, modelOverride: ModelOverride?, - generatorFunction: (ServiceModelCodeGenerator, ModelType) throws -> ()) throws + targetSupport: TargetSupportType, + generatorFunction: (ServiceModelCodeGenerator, ModelType) throws -> ()) throws -> ModelType { let dataList = try modelDirectoryPaths.map { path in try getDataListForModelFiles(atPath: path, fileExtension: fileExtension) @@ -211,13 +265,31 @@ public struct ServiceModelGenerate { model: model, applicationDescription: applicationDescription, customizations: customizations, - modelOverride: modelOverride) + modelOverride: modelOverride, + targetSupport: targetSupport) try generatorFunction(codeGenerator, model) return model } + public static func generateFromModel( + modelDirectoryPaths: [String], + fileExtension: String, + customizations: CodeGenerationCustomizations, + applicationDescription: ApplicationDescription, + modelOverride: ModelOverride?, + generatorFunction: (ServiceModelCodeGenerator, ModelType) throws -> ()) throws + -> ModelType { + return try generateFromModel(modelDirectoryPaths: modelDirectoryPaths, + fileExtension: fileExtension, + customizations: customizations, + applicationDescription: applicationDescription, + modelOverride: modelOverride, + targetSupport: applicationDescription.defaultTargetSupport, + generatorFunction: generatorFunction) + } + private static func getDataListForModelFiles(atPath modelDirectoryPath: String, fileExtension: String) throws -> [Data] { let modelFilePaths = try FileManager.default.contentsOfDirectory(atPath: modelDirectoryPath) @@ -243,3 +315,10 @@ public struct ServiceModelGenerate { } } } + +private extension ApplicationDescription { + var defaultTargetSupport: ModelAndClientTargetSupport { + return ModelAndClientTargetSupport(modelTargetName: "\(self.baseName)Model", + clientTargetName: "\(self.baseName)Client") + } +} From 56a8581013af5e2654fc88dc250a50dbe6279750 Mon Sep 17 00:00:00 2001 From: Simon Pilkington Date: Wed, 28 Sep 2022 13:54:52 -0700 Subject: [PATCH 2/2] Add CI for 5.7, drop 5.4 --- .github/workflows/swift.yml | 18 ++---------------- Package.swift | 2 +- README.md | 2 +- 3 files changed, 4 insertions(+), 18 deletions(-) diff --git a/.github/workflows/swift.yml b/.github/workflows/swift.yml index 6338ce0..7ef4d28 100644 --- a/.github/workflows/swift.yml +++ b/.github/workflows/swift.yml @@ -12,26 +12,12 @@ jobs: strategy: matrix: os: [ubuntu-20.04] - swift: ["5.6", "5.5.3"] + swift: ["5.7", "5.6.3", "5.5.3"] runs-on: ${{ matrix.os }} steps: - - uses: fwal/setup-swift@v1.14.0 + - uses: swift-actions/setup-swift@v1.18.0 with: swift-version: ${{ matrix.swift }} - uses: actions/checkout@v2 - name: Build run: swift build -c release - BuildOpenAPIWorkaround: - name: Swift ${{ matrix.swift }} on ${{ matrix.os }} - strategy: - matrix: - os: [ubuntu-20.04] - swift: ["5.4.3"] - runs-on: ${{ matrix.os }} - steps: - - uses: fwal/setup-swift@v1.14.0 - with: - swift-version: ${{ matrix.swift }} - - uses: actions/checkout@v2 - - name: Build - run: swift build -Xswiftc -Xfrontend -Xswiftc -sil-verify-none -c release diff --git a/Package.swift b/Package.swift index 87eb22b..1265449 100644 --- a/Package.swift +++ b/Package.swift @@ -1,4 +1,4 @@ -// swift-tools-version:5.4 +// swift-tools-version:5.5 // // Copyright 2019-2022 Amazon.com, Inc. or its affiliates. All Rights Reserved. // diff --git a/README.md b/README.md index 83f8c73..33c8e06 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ Build - main Branch -Swift 5.4, 5.5 and 5.6 Tested +Swift 5.5, 5.6 and 5.7 Tested Join the Smoke Server Side community on gitter