Skip to content

Commit

Permalink
Use per-type imports everywhere (#264)
Browse files Browse the repository at this point in the history
### Motivation

The PR #184 broke the build when Foundation.Date was used in specific
locations on client/server.

### Modifications

Fixed the bug, but also made things even more consistent by using
per-type imports on all platforms.

### Result

All the necessary Foundation imports are now present, plus code got
simplified a bit.

### Test Plan

Now that all platforms emit the same imports (except for the
`@preconcurrency` attribute), it's easier to catch similar issues even
during local dev. Verified on a sample proj this now works correctly.

Updated reference tests.
  • Loading branch information
czechboy0 authored Sep 12, 2023
1 parent ad75749 commit 7364ff4
Show file tree
Hide file tree
Showing 8 changed files with 25 additions and 52 deletions.
23 changes: 8 additions & 15 deletions Sources/_OpenAPIGeneratorCore/Renderer/TextBasedRenderer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -73,37 +73,30 @@ struct TextBasedRenderer: RendererProtocol {

/// Renders a single import statement.
func renderImport(_ description: ImportDescription) -> String {
func render(moduleName: String, moduleTypes: [String]? = nil, spi: String?, preconcurrency: Bool) -> String {
let spiPrefix = spi.map { "@_spi(\($0)) " } ?? ""
func render(preconcurrency: Bool) -> String {
let spiPrefix = description.spi.map { "@_spi(\($0)) " } ?? ""
let preconcurrencyPrefix = preconcurrency ? "@preconcurrency " : ""
var types = [String]()
if let moduleTypes, preconcurrency {
if let moduleTypes = description.moduleTypes {
types = moduleTypes.map {
"\(preconcurrencyPrefix)\(spiPrefix)import \($0)"
}
return types.joinedLines()
}
return "\(preconcurrencyPrefix)\(spiPrefix)import \(moduleName)"
return "\(preconcurrencyPrefix)\(spiPrefix)import \(description.moduleName)"
}

switch description.preconcurrency {
case .always:
return render(moduleName: description.moduleName, spi: description.spi, preconcurrency: true)
return render(preconcurrency: true)
case .never:
return render(moduleName: description.moduleName, spi: description.spi, preconcurrency: false)
return render(preconcurrency: false)
case .onOS(let operatingSystems):
var lines = [String]()
lines.append("#if \(operatingSystems.map { "os(\($0))" }.joined(separator: " || "))")
lines.append(
render(
moduleName: description.moduleName,
moduleTypes: description.moduleTypes,
spi: description.spi,
preconcurrency: true
)
)
lines.append(render(preconcurrency: true))
lines.append("#else")
lines.append(render(moduleName: description.moduleName, spi: description.spi, preconcurrency: false))
lines.append(render(preconcurrency: false))
lines.append("#endif")
return lines.joinedLines()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ struct ClientFileTranslator: FileTranslator {

let imports =
Constants.File.imports
+ Constants.Client.scopedImports
+ config.additionalImports
.map { ImportDescription(moduleName: $0) }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,12 @@ enum Constants {

/// The descriptions of modules imported by every generated file.
static let imports: [ImportDescription] = [
ImportDescription(moduleName: "OpenAPIRuntime", spi: "Generated")
ImportDescription(moduleName: "OpenAPIRuntime", spi: "Generated"),
ImportDescription(
moduleName: "Foundation",
moduleTypes: ["struct Foundation.URL", "struct Foundation.Data", "struct Foundation.Date"],
preconcurrency: .onOS(["Linux"])
),
]
}

Expand Down Expand Up @@ -61,15 +66,6 @@ enum Constants {
/// Constants related to the generated client type.
enum Client {

/// An array of scoped imports specific to the `Client` namespace.
static let scopedImports: [ImportDescription] = [
ImportDescription(
moduleName: "Foundation",
moduleTypes: ["struct Foundation.URL", "struct Foundation.Data"],
preconcurrency: .onOS(["Linux"])
)
]

/// The name of the client type.
static let typeName: String = "Client"

Expand Down Expand Up @@ -99,30 +95,9 @@ enum Constants {
}
}

enum Types {

/// An array of scoped imports specific to the `Types` namespace.
static let scopedImports: [ImportDescription] = [
ImportDescription(
moduleName: "Foundation",
moduleTypes: ["struct Foundation.URL", "struct Foundation.Data", "struct Foundation.Date"],
preconcurrency: .onOS(["Linux"])
)
]
}

/// Constants related to the generated server types.
enum Server {

/// An array of scoped imports specific to the `Server` namespace.
static let scopedImports: [ImportDescription] = [
ImportDescription(
moduleName: "Foundation",
moduleTypes: ["struct Foundation.URL", "struct Foundation.Data"],
preconcurrency: .onOS(["Linux"])
)
]

/// Constants related to the universal server.
enum Universal {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ struct ServerFileTranslator: FileTranslator {

let imports =
Constants.File.imports
+ Constants.Server.scopedImports
+ config.additionalImports
.map { ImportDescription(moduleName: $0) }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ struct TypesFileTranslator: FileTranslator {

let imports =
Constants.File.imports
+ Constants.Types.scopedImports
+ config.additionalImports
.map { ImportDescription(moduleName: $0) }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@
#if os(Linux)
@preconcurrency import struct Foundation.URL
@preconcurrency import struct Foundation.Data
@preconcurrency import struct Foundation.Date
#else
import Foundation
import struct Foundation.URL
import struct Foundation.Data
import struct Foundation.Date
#endif
/// Service for managing pet metadata.
///
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@
#if os(Linux)
@preconcurrency import struct Foundation.URL
@preconcurrency import struct Foundation.Data
@preconcurrency import struct Foundation.Date
#else
import Foundation
import struct Foundation.URL
import struct Foundation.Data
import struct Foundation.Date
#endif
extension APIProtocol {
/// Registers each operation handler with the provided transport.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
@preconcurrency import struct Foundation.Data
@preconcurrency import struct Foundation.Date
#else
import Foundation
import struct Foundation.URL
import struct Foundation.Data
import struct Foundation.Date
#endif
/// A type that performs HTTP operations defined by the OpenAPI document.
public protocol APIProtocol: Sendable {
Expand Down

0 comments on commit 7364ff4

Please sign in to comment.