Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
198 changes: 174 additions & 24 deletions Sources/GRPCCodeGen/Internal/Renderer/TextBasedRenderer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -202,11 +202,11 @@ struct TextBasedRenderer: RendererProtocol {
}

/// Renders the specified identifier.
func renderedIdentifier(_ identifier: IdentifierDescription) -> String {
func renderIdentifier(_ identifier: IdentifierDescription) {
switch identifier {
case .pattern(let string): return string
case .pattern(let string): writer.writeLine(string)
case .type(let existingTypeDescription):
return renderedExistingTypeDescription(existingTypeDescription)
renderExistingTypeDescription(existingTypeDescription)
}
}

Expand Down Expand Up @@ -446,7 +446,7 @@ struct TextBasedRenderer: RendererProtocol {
switch expression {
case .literal(let literalDescription): renderLiteral(literalDescription)
case .identifier(let identifierDescription):
writer.writeLine(renderedIdentifier(identifierDescription))
renderIdentifier(identifierDescription)
case .memberAccess(let memberAccessDescription): renderMemberAccess(memberAccessDescription)
case .functionCall(let functionCallDescription): renderFunctionCall(functionCallDescription)
case .assignment(let assignment): renderAssignment(assignment)
Expand Down Expand Up @@ -534,20 +534,44 @@ struct TextBasedRenderer: RendererProtocol {
}

/// Renders the specified type reference to an existing type.
func renderedExistingTypeDescription(_ type: ExistingTypeDescription) -> String {
func renderExistingTypeDescription(_ type: ExistingTypeDescription) {
switch type {
case .any(let existingTypeDescription):
return "any \(renderedExistingTypeDescription(existingTypeDescription))"
writer.writeLine("any ")
writer.nextLineAppendsToLastLine()
renderExistingTypeDescription(existingTypeDescription)
case .generic(let wrapper, let wrapped):
return
"\(renderedExistingTypeDescription(wrapper))<\(renderedExistingTypeDescription(wrapped))>"
renderExistingTypeDescription(wrapper)
writer.nextLineAppendsToLastLine()
writer.writeLine("<")
writer.nextLineAppendsToLastLine()
renderExistingTypeDescription(wrapped)
writer.nextLineAppendsToLastLine()
writer.writeLine(">")
case .optional(let existingTypeDescription):
return "\(renderedExistingTypeDescription(existingTypeDescription))?"
case .member(let components): return components.joined(separator: ".")
renderExistingTypeDescription(existingTypeDescription)
writer.nextLineAppendsToLastLine()
writer.writeLine("?")
case .member(let components):
writer.writeLine(components.joined(separator: "."))
case .array(let existingTypeDescription):
return "[\(renderedExistingTypeDescription(existingTypeDescription))]"
writer.writeLine("[")
writer.nextLineAppendsToLastLine()
renderExistingTypeDescription(existingTypeDescription)
writer.nextLineAppendsToLastLine()
writer.writeLine("]")
case .dictionaryValue(let existingTypeDescription):
return "[String: \(renderedExistingTypeDescription(existingTypeDescription))]"
writer.writeLine("[String: ")
writer.nextLineAppendsToLastLine()
renderExistingTypeDescription(existingTypeDescription)
writer.nextLineAppendsToLastLine()
writer.writeLine("]")
case .some(let existingTypeDescription):
writer.writeLine("some ")
writer.nextLineAppendsToLastLine()
renderExistingTypeDescription(existingTypeDescription)
case .closure(let closureSignatureDescription):
renderClosureSignature(closureSignatureDescription)
}
}

Expand All @@ -558,9 +582,11 @@ struct TextBasedRenderer: RendererProtocol {
words.append(renderedAccessModifier(accessModifier))
}
words.append(contentsOf: [
"typealias", alias.name, "=", renderedExistingTypeDescription(alias.existingType),
"typealias", alias.name, "=",
])
writer.writeLine(words.joinedWords())
writer.writeLine(words.joinedWords() + " ")
writer.nextLineAppendsToLastLine()
renderExistingTypeDescription(alias.existingType)
}

/// Renders the specified binding kind.
Expand All @@ -587,7 +613,9 @@ struct TextBasedRenderer: RendererProtocol {
renderExpression(variable.left)
if let type = variable.type {
writer.nextLineAppendsToLastLine()
writer.writeLine(": \(renderedExistingTypeDescription(type))")
writer.writeLine(": ")
writer.nextLineAppendsToLastLine()
renderExistingTypeDescription(type)
}
}

Expand Down Expand Up @@ -703,11 +731,12 @@ struct TextBasedRenderer: RendererProtocol {
}

/// Renders the specified enum case associated value.
func renderedEnumCaseAssociatedValue(_ value: EnumCaseAssociatedValueDescription) -> String {
func renderEnumCaseAssociatedValue(_ value: EnumCaseAssociatedValueDescription) {
var words: [String] = []
if let label = value.label { words.append(label + ":") }
words.append(renderedExistingTypeDescription(value.type))
return words.joinedWords()
writer.writeLine(words.joinedWords())
writer.nextLineAppendsToLastLine()
renderExistingTypeDescription(value.type)
}

/// Renders the specified enum case declaration.
Expand All @@ -722,9 +751,13 @@ struct TextBasedRenderer: RendererProtocol {
renderLiteral(rawValue)
case .nameWithAssociatedValues(let values):
if values.isEmpty { break }
let associatedValues = values.map(renderedEnumCaseAssociatedValue).joined(separator: ", ")
writer.nextLineAppendsToLastLine()
writer.writeLine("(\(associatedValues))")
for (value, isLast) in values.enumeratedWithLastMarker() {
renderEnumCaseAssociatedValue(value)
if !isLast {
writer.nextLineAppendsToLastLine()
writer.writeLine(", ")
}
}
}
}

Expand All @@ -750,7 +783,9 @@ struct TextBasedRenderer: RendererProtocol {
func renderedFunctionKind(_ functionKind: FunctionKind) -> String {
switch functionKind {
case .initializer(let isFailable): return "init\(isFailable ? "?" : "")"
case .function(let name, let isStatic): return (isStatic ? "static " : "") + "func \(name)"
case .function(let name, let isStatic):
return (isStatic ? "static " : "") + "func \(name)"

}
}

Expand All @@ -759,6 +794,54 @@ struct TextBasedRenderer: RendererProtocol {
switch keyword {
case .throws: return "throws"
case .async: return "async"
case .rethrows: return "rethrows"
}
}

/// Renders the specified function signature.
func renderClosureSignature(_ signature: ClosureSignatureDescription) {
if signature.sendable {
writer.writeLine("@Sendable ")
writer.nextLineAppendsToLastLine()
}
if signature.escaping {
writer.writeLine("@escaping ")
writer.nextLineAppendsToLastLine()
}

writer.writeLine("(")
let parameters = signature.parameters
let separateLines = parameters.count > 1
if separateLines {
writer.withNestedLevel {
for (parameter, isLast) in signature.parameters.enumeratedWithLastMarker() {
renderClosureParameter(parameter)
if !isLast {
writer.nextLineAppendsToLastLine()
writer.writeLine(",")
}
}
}
} else {
writer.nextLineAppendsToLastLine()
if let parameter = parameters.first {
renderClosureParameter(parameter)
writer.nextLineAppendsToLastLine()
}
}
writer.writeLine(")")

let keywords = signature.keywords
for keyword in keywords {
writer.nextLineAppendsToLastLine()
writer.writeLine(" " + renderedFunctionKeyword(keyword))
}

if let returnType = signature.returnType {
writer.nextLineAppendsToLastLine()
writer.writeLine(" -> ")
writer.nextLineAppendsToLastLine()
renderExpression(returnType)
}
}

Expand All @@ -769,7 +852,26 @@ struct TextBasedRenderer: RendererProtocol {
writer.writeLine(renderedAccessModifier(accessModifier) + " ")
writer.nextLineAppendsToLastLine()
}
writer.writeLine(renderedFunctionKind(signature.kind) + "(")
let generics = signature.generics
writer.writeLine(
renderedFunctionKind(signature.kind)
)
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()
writer.writeLine("(")
let parameters = signature.parameters
let separateLines = parameters.count > 1
if separateLines {
Expand Down Expand Up @@ -806,6 +908,11 @@ struct TextBasedRenderer: RendererProtocol {
writer.nextLineAppendsToLastLine()
renderExpression(returnType)
}

if let whereClause = signature.whereClause {
writer.nextLineAppendsToLastLine()
writer.writeLine(" " + renderedWhereClause(whereClause))
}
}

/// Renders the specified function declaration.
Expand Down Expand Up @@ -839,11 +946,54 @@ struct TextBasedRenderer: RendererProtocol {
}
writer.writeLine(": ")
writer.nextLineAppendsToLastLine()

if parameterDescription.inout {
writer.writeLine("inout ")
writer.nextLineAppendsToLastLine()
}

if let type = parameterDescription.type {
renderExistingTypeDescription(type)
}

if let defaultValue = parameterDescription.defaultValue {
writer.nextLineAppendsToLastLine()
writer.writeLine(" = ")
writer.nextLineAppendsToLastLine()
renderExpression(defaultValue)
}
}

/// Renders the specified parameter declaration for a closure.
func renderClosureParameter(_ parameterDescription: ParameterDescription) {
let name = parameterDescription.name
let label: String
if let declaredLabel = parameterDescription.label {
label = declaredLabel
} else {
label = "_"
}

if let name = name {
writer.writeLine(label)
if name != parameterDescription.label {
// If the label and name are the same value, don't repeat it.
writer.writeLine(" ")
writer.nextLineAppendsToLastLine()
writer.writeLine(name)
writer.nextLineAppendsToLastLine()
}
}

if parameterDescription.inout {
writer.writeLine("inout ")
writer.nextLineAppendsToLastLine()
}
writer.writeLine(renderedExistingTypeDescription(parameterDescription.type))

if let type = parameterDescription.type {
renderExistingTypeDescription(type)
}

if let defaultValue = parameterDescription.defaultValue {
writer.nextLineAppendsToLastLine()
writer.writeLine(" = ")
Expand Down
Loading