diff --git a/Sources/_OpenAPIGeneratorCore/Layers/RenderedSwiftRepresentation.swift b/Sources/_OpenAPIGeneratorCore/Layers/RenderedSwiftRepresentation.swift index 3a9c89e3..90ea4b72 100644 --- a/Sources/_OpenAPIGeneratorCore/Layers/RenderedSwiftRepresentation.swift +++ b/Sources/_OpenAPIGeneratorCore/Layers/RenderedSwiftRepresentation.swift @@ -11,13 +11,12 @@ // SPDX-License-Identifier: Apache-2.0 // //===----------------------------------------------------------------------===// -#if os(Linux) -@preconcurrency import struct Foundation.URL -@preconcurrency import struct Foundation.Data -#else +#if canImport(Darwin) import struct Foundation.URL -import struct Foundation.Data +#else +@preconcurrency import struct Foundation.URL #endif +import struct Foundation.Data /// An in-memory file that contains the generated Swift code. typealias RenderedSwiftRepresentation = InMemoryOutputFile diff --git a/Sources/_OpenAPIGeneratorCore/Layers/StructuredSwiftRepresentation.swift b/Sources/_OpenAPIGeneratorCore/Layers/StructuredSwiftRepresentation.swift index 4cf1dab0..6ebe0570 100644 --- a/Sources/_OpenAPIGeneratorCore/Layers/StructuredSwiftRepresentation.swift +++ b/Sources/_OpenAPIGeneratorCore/Layers/StructuredSwiftRepresentation.swift @@ -38,12 +38,21 @@ struct ImportDescription: Equatable, Codable { /// Describes any requirement for the `@preconcurrency` attribute. enum PreconcurrencyRequirement: Equatable, Codable { + + /// Platform requirement. + enum Requirement: Equatable, Codable { + /// Can import a certain library. + case canImport(String) + /// Swift version greater than or equal to. + case minimumSwift(String) + } + /// The attribute is always required. case always /// The attribute is not required. case never - /// The attribute is required only on the named operating systems. - case onOS([String]) + /// The attribute is required only if not this requirements are met. + case ifNot([Requirement]) } } diff --git a/Sources/_OpenAPIGeneratorCore/Renderer/TextBasedRenderer.swift b/Sources/_OpenAPIGeneratorCore/Renderer/TextBasedRenderer.swift index e0f00e99..34c17185 100644 --- a/Sources/_OpenAPIGeneratorCore/Renderer/TextBasedRenderer.swift +++ b/Sources/_OpenAPIGeneratorCore/Renderer/TextBasedRenderer.swift @@ -162,11 +162,12 @@ struct TextBasedRenderer: RendererProtocol { switch description.preconcurrency { case .always: render(preconcurrency: true) case .never: render(preconcurrency: false) - case .onOS(let operatingSystems): - writer.writeLine("#if \(operatingSystems.map { "os(\($0))" }.joined(separator: " || "))") - render(preconcurrency: true) - writer.writeLine("#else") + case .ifNot(let requirements): + precondition(!requirements.isEmpty) + writer.writeLine("#if \(requirements.map { $0.render() }.joined(separator: " || "))") render(preconcurrency: false) + writer.writeLine("#else") + render(preconcurrency: true) writer.writeLine("#endif") } } @@ -899,3 +900,12 @@ extension TextBasedRenderer { return renderer.renderedContents() } } + +private extension ImportDescription.PreconcurrencyRequirement.Requirement { + func render() -> String { + switch self { + case let .canImport(name): return "canImport(\(name))" + case let .minimumSwift(version): return "swift(>=\(version))" + } + } +} diff --git a/Sources/_OpenAPIGeneratorCore/Translator/CommonTypes/Constants.swift b/Sources/_OpenAPIGeneratorCore/Translator/CommonTypes/Constants.swift index e72337ee..bcb6c960 100644 --- a/Sources/_OpenAPIGeneratorCore/Translator/CommonTypes/Constants.swift +++ b/Sources/_OpenAPIGeneratorCore/Translator/CommonTypes/Constants.swift @@ -26,10 +26,16 @@ enum Constants { /// The descriptions of modules imported by every generated file. static let imports: [ImportDescription] = [ ImportDescription(moduleName: "OpenAPIRuntime", spi: "Generated"), + ImportDescription(moduleName: "Foundation", moduleTypes: ["struct Foundation.Data"]), ImportDescription( moduleName: "Foundation", - moduleTypes: ["struct Foundation.URL", "struct Foundation.Data", "struct Foundation.Date"], - preconcurrency: .onOS(["Linux"]) + moduleTypes: ["struct Foundation.Date"], + preconcurrency: .ifNot([.canImport("Darwin"), .minimumSwift("5.9.1")]) + ), + ImportDescription( + moduleName: "Foundation", + moduleTypes: ["struct Foundation.URL"], + preconcurrency: .ifNot([.canImport("Darwin")]) ), ] diff --git a/Sources/swift-openapi-generator/Documentation.docc/Proposals/SOAR-0007.md b/Sources/swift-openapi-generator/Documentation.docc/Proposals/SOAR-0007.md index 0eeeba34..f1b835fb 100644 --- a/Sources/swift-openapi-generator/Documentation.docc/Proposals/SOAR-0007.md +++ b/Sources/swift-openapi-generator/Documentation.docc/Proposals/SOAR-0007.md @@ -173,7 +173,7 @@ public enum Operations { This proposal covers generating the following additional API surface to simplify providing inputs. - + ```swift extension APIProtocol { // The parameters to each overload will match those of the corresponding @@ -194,7 +194,7 @@ extension APIProtocol { This proposal also covers generating the following additional API surface to simplify handling outputs. -```swift +```swift // Note: Generating an extension is not prescriptive; implementations may // generate these properties within the primary type definition. extension Operations.getGreeting.Output { @@ -313,15 +313,18 @@ Generated using the following command: // ----------- // Generated by swift-openapi-generator, do not modify. @_spi(Generated) import OpenAPIRuntime -#if os(Linux) -@preconcurrency import struct Foundation.URL -@preconcurrency import struct Foundation.Data -@preconcurrency import struct Foundation.Date -#else -import struct Foundation.URL import struct Foundation.Data +#if os(Darwin) || swift(>=5.9.1) import struct Foundation.Date +#else +@preconcurrency import struct Foundation.Date +#endif +#if os(Darwin) +import struct Foundation.URL +#else +@preconcurrency import struct Foundation.URL #endif + /// A type that performs HTTP operations defined by the OpenAPI document. public protocol APIProtocol: Sendable { /// - Remark: HTTP `GET /greet`. diff --git a/Sources/swift-openapi-generator/runGenerator.swift b/Sources/swift-openapi-generator/runGenerator.swift index 08b62d46..6f6eac9a 100644 --- a/Sources/swift-openapi-generator/runGenerator.swift +++ b/Sources/swift-openapi-generator/runGenerator.swift @@ -11,13 +11,12 @@ // SPDX-License-Identifier: Apache-2.0 // //===----------------------------------------------------------------------===// -#if os(Linux) -@preconcurrency import struct Foundation.URL -@preconcurrency import struct Foundation.Data -#else +#if canImport(Darwin) import struct Foundation.URL -import struct Foundation.Data +#else +@preconcurrency import struct Foundation.URL #endif +import struct Foundation.Data import class Foundation.FileManager import ArgumentParser import _OpenAPIGeneratorCore diff --git a/Tests/OpenAPIGeneratorCoreTests/Renderer/Test_TextBasedRenderer.swift b/Tests/OpenAPIGeneratorCoreTests/Renderer/Test_TextBasedRenderer.swift index 79d23804..fccaf98c 100644 --- a/Tests/OpenAPIGeneratorCoreTests/Renderer/Test_TextBasedRenderer.swift +++ b/Tests/OpenAPIGeneratorCoreTests/Renderer/Test_TextBasedRenderer.swift @@ -93,13 +93,18 @@ final class Test_TextBasedRenderer: XCTestCase { """# ) try _test( - [ImportDescription(moduleName: "Foo", preconcurrency: .onOS(["Bar", "Baz"]))], + [ + ImportDescription( + moduleName: "Foo", + preconcurrency: .ifNot([.canImport("Darwin"), .minimumSwift("5.9.1")]) + ) + ], renderedBy: TextBasedRenderer.renderImports, rendersAs: #""" - #if os(Bar) || os(Baz) - @preconcurrency import Foo - #else + #if canImport(Darwin) || swift(>=5.9.1) import Foo + #else + @preconcurrency import Foo #endif """# ) diff --git a/Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Petstore/Client.swift b/Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Petstore/Client.swift index ee9fc11c..4c4b29c7 100644 --- a/Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Petstore/Client.swift +++ b/Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Petstore/Client.swift @@ -1,13 +1,15 @@ // Generated by swift-openapi-generator, do not modify. @_spi(Generated) import OpenAPIRuntime -#if os(Linux) -@preconcurrency import struct Foundation.URL -@preconcurrency import struct Foundation.Data -@preconcurrency import struct Foundation.Date -#else -import struct Foundation.URL import struct Foundation.Data +#if canImport(Darwin) || swift(>=5.9.1) import struct Foundation.Date +#else +@preconcurrency import struct Foundation.Date +#endif +#if canImport(Darwin) +import struct Foundation.URL +#else +@preconcurrency import struct Foundation.URL #endif import HTTPTypes /// Service for managing pet metadata. diff --git a/Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Petstore/Server.swift b/Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Petstore/Server.swift index 80d642b3..01a78170 100644 --- a/Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Petstore/Server.swift +++ b/Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Petstore/Server.swift @@ -1,13 +1,15 @@ // Generated by swift-openapi-generator, do not modify. @_spi(Generated) import OpenAPIRuntime -#if os(Linux) -@preconcurrency import struct Foundation.URL -@preconcurrency import struct Foundation.Data -@preconcurrency import struct Foundation.Date -#else -import struct Foundation.URL import struct Foundation.Data +#if canImport(Darwin) || swift(>=5.9.1) import struct Foundation.Date +#else +@preconcurrency import struct Foundation.Date +#endif +#if canImport(Darwin) +import struct Foundation.URL +#else +@preconcurrency import struct Foundation.URL #endif import HTTPTypes extension APIProtocol { diff --git a/Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Petstore/Types.swift b/Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Petstore/Types.swift index 66b5e4c9..fd8f37ec 100644 --- a/Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Petstore/Types.swift +++ b/Tests/OpenAPIGeneratorReferenceTests/Resources/ReferenceSources/Petstore/Types.swift @@ -1,13 +1,15 @@ // Generated by swift-openapi-generator, do not modify. @_spi(Generated) import OpenAPIRuntime -#if os(Linux) -@preconcurrency import struct Foundation.URL -@preconcurrency import struct Foundation.Data -@preconcurrency import struct Foundation.Date -#else -import struct Foundation.URL import struct Foundation.Data +#if canImport(Darwin) || swift(>=5.9.1) import struct Foundation.Date +#else +@preconcurrency import struct Foundation.Date +#endif +#if canImport(Darwin) +import struct Foundation.URL +#else +@preconcurrency import struct Foundation.URL #endif /// A type that performs HTTP operations defined by the OpenAPI document. public protocol APIProtocol: Sendable {