Skip to content

Commit

Permalink
Extend structured swift to support generic structs (#2154)
Browse files Browse the repository at this point in the history
Motivation:

The structured swift representation we're using doesn't support generic
struct at the moment. We'll need this for an upcoming change.

Modifications:

- Allow for generic structs with where clauses to be represented and
rendered.

Result:

Generic structs can be rendered
  • Loading branch information
glbrntt authored Jan 13, 2025
1 parent 560c6c7 commit 76073a2
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 1 deletion.
21 changes: 21 additions & 0 deletions Sources/GRPCCodeGen/Internal/Renderer/TextBasedRenderer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -740,10 +740,31 @@ struct TextBasedRenderer: RendererProtocol {
}
writer.writeLine("struct \(structDesc.name)")
writer.nextLineAppendsToLastLine()
let generics = structDesc.generics
if !generics.isEmpty {
writer.nextLineAppendsToLastLine()
writer.writeLine("<")
for (genericType, isLast) in generics.enumeratedWithLastMarker() {
writer.nextLineAppendsToLastLine()
renderExistingTypeDescription(genericType)
if !isLast {
writer.nextLineAppendsToLastLine()
writer.writeLine(", ")
}
}
writer.nextLineAppendsToLastLine()
writer.writeLine(">")
writer.nextLineAppendsToLastLine()
}
if !structDesc.conformances.isEmpty {
writer.writeLine(": \(structDesc.conformances.joined(separator: ", "))")
writer.nextLineAppendsToLastLine()
}
if let whereClause = structDesc.whereClause {
writer.nextLineAppendsToLastLine()
writer.writeLine(" " + renderedWhereClause(whereClause))
writer.nextLineAppendsToLastLine()
}
writer.writeLine(" {")
if !structDesc.members.isEmpty {
writer.withNestedLevel {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -401,11 +401,17 @@ struct StructDescription: Equatable, Codable, Sendable {
/// For example, in `struct Foo {`, `name` is `Foo`.
var name: String

/// The generic types of the struct.
var generics: [ExistingTypeDescription] = []

/// The type names that the struct conforms to.
///
/// For example: `["Sendable", "Codable"]`.
var conformances: [String] = []

/// A where clause constraining the struct declaration.
var whereClause: WhereClause? = nil

/// The declarations that make up the main struct body.
var members: [Declaration] = []
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -820,12 +820,62 @@ final class Test_TextBasedRenderer: XCTestCase {
func testStruct() throws {
try _test(
.init(name: "Structy"),
StructDescription(name: "Structy"),
renderedBy: { $0.renderStruct(_:) },
rendersAs: #"""
struct Structy {}
"""#
)
try _test(
StructDescription(
name: "Structy",
conformances: ["Foo"]
),
renderedBy: { $0.renderStruct(_:) },
rendersAs: #"""
struct Structy: Foo {}
"""#
)
try _test(
StructDescription(
name: "Structy",
generics: [.member("T")]
),
renderedBy: { $0.renderStruct(_:) },
rendersAs: #"""
struct Structy<T> {}
"""#
)
try _test(
StructDescription(
name: "Structy",
generics: [.member("T")],
whereClause: WhereClause(
requirements: [
.conformance("T", "Foo"),
.conformance("T", "Sendable"),
]
)
),
renderedBy: {
$0.renderStruct(_:)
},
rendersAs: #"""
struct Structy<T> where T: Foo, T: Sendable {}
"""#
)
try _test(
StructDescription(
name: "Structy",
generics: [.member("T")],
conformances: ["Hashable"],
whereClause: WhereClause(requirements: [.conformance("T", "Foo")])
),
renderedBy: { $0.renderStruct(_:) },
rendersAs: #"""
struct Structy<T>: Hashable where T: Foo {}
"""#
)
}
func testProtocol() throws {
Expand Down

0 comments on commit 76073a2

Please sign in to comment.