Skip to content

Commit

Permalink
Add deprecated init function with deprecated shape members (#34)
Browse files Browse the repository at this point in the history
* Add deprecated init function with deprecated members

* swift format
  • Loading branch information
adam-fowler authored Nov 23, 2021
1 parent 7a80c0f commit 933c2d1
Show file tree
Hide file tree
Showing 7 changed files with 85 additions and 50 deletions.
17 changes: 13 additions & 4 deletions Sources/SotoCodeGenerator/AwsService+shapes.swift
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,8 @@ extension AwsService {
shapeOptions.append("allowStreaming")
if !payload.hasTrait(type: RequiresLengthTrait.self),
let operationShape = operationShape,
operationShape.hasTrait(type: AwsAuthUnsignedPayloadTrait.self) {
operationShape.hasTrait(type: AwsAuthUnsignedPayloadTrait.self)
{
shapeOptions.append("allowChunkedStreaming")
}
}
Expand All @@ -140,7 +141,9 @@ extension AwsService {
xmlNamespace = shape.trait(type: XmlNamespaceTrait.self)?.uri
}
let recursive = doesShapeHaveRecursiveOwnReference(shape, shapeId: shapeId)

let initParameters = contexts.members.compactMap {
!$0.deprecated ? InitParamContext(parameter: $0.parameter, type: $0.type, default: $0.default) : nil
}
return StructureContext(
object: recursive ? "class" : "struct",
name: shapeName.toSwiftClassCase(),
Expand All @@ -152,10 +155,12 @@ extension AwsService {
isDecodable: shape.hasTrait(type: SotoOutputShapeTrait.self),
encoding: contexts.encoding,
members: contexts.members,
initParameters: initParameters,
awsShapeMembers: contexts.awsShapeMembers,
codingKeys: contexts.codingKeys,
validation: contexts.validation,
requiresDefaultValidation: contexts.validation.count != contexts.members.count
requiresDefaultValidation: contexts.validation.count != contexts.members.count,
deprecatedMembers: contexts.members.compactMap { $0.deprecated ? $0.parameter : nil }
)
}

Expand Down Expand Up @@ -207,6 +212,9 @@ extension AwsService {
func generateMemberContext(_ member: MemberShape, name: String, shapeName: String, typeIsEnum: Bool) -> MemberContext {
let required = member.hasTrait(type: RequiredTrait.self)
let idempotencyToken = member.hasTrait(type: IdempotencyTokenTrait.self)
let deprecated = member.hasTrait(type: DeprecatedTrait.self)
precondition((required && deprecated) == false, "Member cannot be required and deprecated")

let defaultValue: String?
if idempotencyToken == true {
defaultValue = "\(shapeName.toSwiftClassCase()).idempotencyToken()"
Expand All @@ -224,7 +232,8 @@ extension AwsService {
propertyWrapper: self.generatePropertyWrapper(member, name: name, required: required),
type: type + ((required || typeIsEnum) ? "" : "?"),
comment: processMemberDocs(from: member),
duplicate: false // NEED to catch this
deprecated: deprecated,
duplicate: false // TODO: NEED to catch this
)
}

Expand Down
19 changes: 15 additions & 4 deletions Sources/SotoCodeGenerator/AwsService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ struct AwsService {
self.serviceEndpointPrefix = try Self.getServiceEndpointPrefix(service: service.value, id: service.key) ?? serviceName.lowercased()
self.serviceProtocolTrait = try Self.getServiceProtocol(service.value)


self.operations = Self.getOperations(service.value, model: model)

self.endpoints = endpoints
Expand Down Expand Up @@ -70,7 +69,7 @@ struct AwsService {
.components(separatedBy: CharacterSet.alphanumerics.inverted)
.map { $0.prefix(1).capitalized + $0.dropFirst() }
.joined()

return serviceName
}

Expand Down Expand Up @@ -106,7 +105,7 @@ struct AwsService {
context["xmlNamespace"] = service.trait(type: XmlNamespaceTrait.self)?.uri
context["middlewareClass"] = self.getMiddleware(for: service)
context["endpointDiscovery"] = service.trait(type: AwsClientEndpointDiscoveryTrait.self)?.operation.shapeName.toSwiftVariableCase()

let endpoints = self.getServiceEndpoints()
.sorted { $0.key < $1.key }
.map { "\"\($0.key)\": \"\($0.value)\"" }
Expand Down Expand Up @@ -157,6 +156,8 @@ struct AwsService {
// construct array of input shape parameters to use in `usingPaginationToken` function
var initParams: [String: String] = [:]
for member in inputShape.members ?? [:] {
// don't include deprecated members
guard !member.value.hasTrait(type: DeprecatedTrait.self) else { continue }
initParams[member.key.toSwiftLabelCase()] = "self.\(member.key.toSwiftLabelCase())"
}
initParams[inputToken.toSwiftLabelCase()] = "token"
Expand Down Expand Up @@ -552,7 +553,7 @@ struct AwsService {
// return dictionary of partition endpoints keyed by endpoint name
func getPartitionEndpoints() -> [String: (endpoint: String, region: Region)] {
var partitionEndpoints: [String: (endpoint: String, region: Region)] = [:]
endpoints.partitions.forEach {
self.endpoints.partitions.forEach {
if let partitionEndpoint = $0.services[self.serviceEndpointPrefix]?.partitionEndpoint {
guard let service = $0.services[self.serviceEndpointPrefix],
let endpoint = service.endpoints[partitionEndpoint],
Expand Down Expand Up @@ -607,6 +608,7 @@ extension AwsService {
struct DiscoverableEndpoint {
let required: Bool
}

let comment: [String.SubSequence]
let funcName: String
let inputShape: String?
Expand Down Expand Up @@ -670,9 +672,16 @@ extension AwsService {
let propertyWrapper: String?
let type: String
let comment: [String.SubSequence]
let deprecated: Bool
var duplicate: Bool
}

struct InitParamContext {
let parameter: String
let type: String
let `default`: String?
}

struct MemberEncodingContext {
let name: String
let location: String?
Expand Down Expand Up @@ -735,10 +744,12 @@ extension AwsService {
let isDecodable: Bool
let encoding: [EncodingPropertiesContext]
let members: [MemberContext]
let initParameters: [InitParamContext]
let awsShapeMembers: [MemberEncodingContext]
let codingKeys: [CodingKeysContext]
let validation: [ValidationContext]
let requiresDefaultValidation: Bool
let deprecatedMembers: [String]
}

struct WaiterContext {
Expand Down
2 changes: 1 addition & 1 deletion Sources/SotoCodeGenerator/Patch.swift
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ struct MultiplePatch: ShapePatch {
init(_ patches: ShapePatch...) {
self.init(patches)
}

func patch(shape: Shape) throws -> Shape? {
var shape = shape
for patch in self.patches {
Expand Down
1 change: 1 addition & 0 deletions Sources/SotoCodeGenerator/SotoTraits.swift
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ public struct SotoPaginationTruncatedTrait: StaticTrait {
OrSelector(TypeSelector<OperationShape>(), TypeSelector<ServiceShape>())
)
}

public let isTruncated: String

public init(isTruncated: String) {
Expand Down
80 changes: 40 additions & 40 deletions Sources/SotoCodeGenerator/Templates/api+async.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,53 +14,53 @@

extension Templates {
static let apiAsyncTemplate = """
{{%CONTENT_TYPE:TEXT}}
{{>header}}
{{%CONTENT_TYPE:TEXT}}
{{>header}}
#if compiler(>=5.5) && canImport(_Concurrency)
#if compiler(>=5.5) && canImport(_Concurrency)
import SotoCore
import SotoCore
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *)
extension {{ name }} {
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *)
extension {{ name }} {
// MARK: Async API Calls
{{#operations}}
// MARK: Async API Calls
{{#operations}}
{{#comment}}
/// {{.}}
{{/comment}}
{{#documentationUrl}}
/// {{.}}
{{/documentationUrl}}
{{#deprecated}}
@available(*, deprecated, message:"{{.}}")
{{/deprecated}}
public func {{funcName}}({{#inputShape}}_ input: {{.}}, {{/inputShape}}logger: {{logger}} = AWSClient.loggingDisabled, on eventLoop: EventLoop? = nil) async throws{{#outputShape}} -> {{.}}{{/outputShape}} {
return try await self.client.execute(operation: "{{name}}", path: "{{path}}", httpMethod: .{{httpMethod}}, serviceConfig: self.config{{#inputShape}}, input: input{{/inputShape}}{{#endpointRequired}}, endpointDiscovery: .init(storage: self.endpointStorage, discover: self.getEndpoint, required: {{required}}){{/endpointRequired}}{{#hostPrefix}}, hostPrefix: "{{{.}}}"{{/hostPrefix}}, logger: logger, on: eventLoop)
}
{{/operations}}
{{#first(streamingOperations)}}
{{#comment}}
/// {{.}}
{{/comment}}
{{#documentationUrl}}
/// {{.}}
{{/documentationUrl}}
{{#deprecated}}
@available(*, deprecated, message:"{{.}}")
{{/deprecated}}
public func {{funcName}}({{#inputShape}}_ input: {{.}}, {{/inputShape}}logger: {{logger}} = AWSClient.loggingDisabled, on eventLoop: EventLoop? = nil) async throws{{#outputShape}} -> {{.}}{{/outputShape}} {
return try await self.client.execute(operation: "{{name}}", path: "{{path}}", httpMethod: .{{httpMethod}}, serviceConfig: self.config{{#inputShape}}, input: input{{/inputShape}}{{#endpointRequired}}, endpointDiscovery: .init(storage: self.endpointStorage, discover: self.getEndpoint, required: {{required}}){{/endpointRequired}}{{#hostPrefix}}, hostPrefix: "{{{.}}}"{{/hostPrefix}}, logger: logger, on: eventLoop)
}
{{/operations}}
{{#first(streamingOperations)}}
// MARK: Streaming Async API Calls
{{#streamingOperations}}
// MARK: Streaming Async API Calls
{{#streamingOperations}}
{{#comment}}
/// {{.}}
{{/comment}}
{{#documentationUrl}}
/// {{.}}
{{/documentationUrl}}
{{#deprecated}}
@available(*, deprecated, message:"{{.}}")
{{/deprecated}}
public func {{funcName}}Streaming({{#inputShape}}_ input: {{.}}, {{/inputShape}}logger: {{logger}} = AWSClient.loggingDisabled, on eventLoop: EventLoop? = nil, _ stream: @escaping ({{streaming}}, EventLoop) -> EventLoopFuture<Void>) async throws{{#outputShape}} -> {{.}}{{/outputShape}} {
return try await self.client.execute(operation: "{{name}}", path: "{{path}}", httpMethod: .{{httpMethod}}, serviceConfig: self.config{{#inputShape}}, input: input{{/inputShape}}{{#endpointRequired}}, endpointDiscovery: .init(storage: self.endpointStorage, discover: self.getEndpoint, required: {{required}}){{/endpointRequired}}{{#hostPrefix}}, hostPrefix: "{{{.}}}"{{/hostPrefix}}, logger: logger, on: eventLoop, stream: stream)
}
{{/streamingOperations}}
{{/first(streamingOperations)}}
{{#comment}}
/// {{.}}
{{/comment}}
{{#documentationUrl}}
/// {{.}}
{{/documentationUrl}}
{{#deprecated}}
@available(*, deprecated, message:"{{.}}")
{{/deprecated}}
public func {{funcName}}Streaming({{#inputShape}}_ input: {{.}}, {{/inputShape}}logger: {{logger}} = AWSClient.loggingDisabled, on eventLoop: EventLoop? = nil, _ stream: @escaping ({{streaming}}, EventLoop) -> EventLoopFuture<Void>) async throws{{#outputShape}} -> {{.}}{{/outputShape}} {
return try await self.client.execute(operation: "{{name}}", path: "{{path}}", httpMethod: .{{httpMethod}}, serviceConfig: self.config{{#inputShape}}, input: input{{/inputShape}}{{#endpointRequired}}, endpointDiscovery: .init(storage: self.endpointStorage, discover: self.getEndpoint, required: {{required}}){{/endpointRequired}}{{#hostPrefix}}, hostPrefix: "{{{.}}}"{{/hostPrefix}}, logger: logger, on: eventLoop, stream: stream)
}
{{/streamingOperations}}
{{/first(streamingOperations)}}
}
#endif // compiler(>=5.5) && canImport(_Concurrency)
"""
#endif // compiler(>=5.5) && canImport(_Concurrency)
"""
}
2 changes: 1 addition & 1 deletion Sources/SotoCodeGenerator/Templates/api.swift
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ extension Templates {
{{/streamingOperations}}
{{/first(streamingOperations)}}
{{#endpointDiscovery}}
func getEndpoint(logger: Logger, eventLoop: EventLoop) -> EventLoopFuture<AWSEndpoints> {
return describeEndpoints(.init(), logger: logger, on: eventLoop).map {
.init(endpoints: $0.endpoints.map {
Expand Down
14 changes: 14 additions & 0 deletions Sources/SotoCodeGenerator/Templates/struct.swift
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,25 @@ extension Templates {
{{/members}}
{{! init() function }}
public init({{#initParameters}}{{parameter}}: {{type}}{{#default}} = {{.}}{{/default}}{{^last()}}, {{/last()}}{{/initParameters}}) {
{{#members}}
{{^deprecated}}
self.{{variable}} = {{variable}}
{{/deprecated}}
{{#deprecated}}
self.{{variable}} = {{default}}
{{/deprecated}}
{{/members}}
}
{{! deprecated init() function }}
{{^empty(deprecatedMembers)}}
@available(*, deprecated, message:"Members {{#deprecatedMembers}}{{.}}{{^last()}}, {{/last()}}{{/deprecatedMembers}} have been deprecated")
public init({{#members}}{{parameter}}: {{type}}{{#default}} = {{.}}{{/default}}{{^last()}}, {{/last()}}{{/members}}) {
{{#members}}
self.{{variable}} = {{variable}}
{{/members}}
}
{{/empty(deprecatedMembers)}}
{{! validate() function }}
{{#first(validation)}}
Expand Down

0 comments on commit 933c2d1

Please sign in to comment.