Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Emit JSON path reference in comments for all generated types #196

Merged
merged 10 commits into from
Aug 17, 2023
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,16 @@ extension TypeName {
suffix: generatedFromCommentText
)
}

func docCommentWithUserDescription(_ userDescription: String?, subPath: String) -> Comment? {
guard let fullyQualifiedJSONPath else {
return Comment.doc(prefix: userDescription, suffix: nil)
}
return Comment.doc(
prefix: userDescription,
suffix: "- Remark: Generated from `\(fullyQualifiedJSONPath)/\(subPath)`."
)
}
}

extension ResponseKind {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,10 @@ struct ContentType: Hashable {
var lowercasedTypeAndSubtype: String {
"\(lowercasedType)/\(lowercasedSubtype)"
}

var lowercasedTypeAndSubtypeWithEscape: String {
"\(lowercasedType)\\/\(lowercasedSubtype)"
}

/// The header value used when sending a content-type header.
var headerValueForSending: String {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,11 @@ extension TypesFileTranslator {
} else {
associatedDeclarations = []
}

let comment: Comment? = parent.docCommentWithUserDescription(nil,
subPath: "\(parameter.location.rawValue)/\(parameter.name)")
takeshi-1000 marked this conversation as resolved.
Show resolved Hide resolved
return .init(
comment: comment,
isDeprecated: parameter.parameter.deprecated,
originalName: parameter.name,
typeUsage: parameter.typeUsage,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ extension TypesFileTranslator {
/// - Returns: A list of declarations; empty if the request body is
/// unsupported.
func requestBodyContentCases(
typeName: TypeName,
takeshi-1000 marked this conversation as resolved.
Show resolved Hide resolved
for requestBody: TypedRequestBody
) throws -> [Declaration] {
var bodyMembers: [Declaration] = []
Expand All @@ -54,13 +55,20 @@ extension TypesFileTranslator {
}
let identifier = contentSwiftName(content.content.contentType)
takeshi-1000 marked this conversation as resolved.
Show resolved Hide resolved
let associatedType = content.resolvedTypeUsage
let contentCase: Declaration = .enumCase(
.init(

let subPath: String = {
let contentPath = typeName.isComponent ? "content" : "requestBody/content"
return "\(contentPath)/\(content.content.contentType.lowercasedTypeAndSubtypeWithEscape)"
}()

let contentCase: Declaration = .commentable(
typeName.docCommentWithUserDescription(nil, subPath: subPath),
.enumCase(.init(
takeshi-1000 marked this conversation as resolved.
Show resolved Hide resolved
name: identifier,
kind: .nameWithAssociatedValues([
.init(type: associatedType.fullyQualifiedNonOptionalSwiftName)
])
)
))
)
bodyMembers.append(contentCase)
}
Expand Down Expand Up @@ -131,7 +139,8 @@ extension TypesFileTranslator {
requestBody: TypedRequestBody
) throws -> Declaration {
let type = requestBody.typeUsage.typeName
let members = try requestBodyContentCases(for: requestBody)
let members = try requestBodyContentCases(typeName: type,
for: requestBody)
takeshi-1000 marked this conversation as resolved.
Show resolved Hide resolved
return translateRequestBodyInTypes(
typeName: type,
members: members
Expand All @@ -154,7 +163,14 @@ extension TypesFileTranslator {
conformances: Constants.Operation.Output.conformances,
members: members
)
return bodyEnumDecl
let comment: Comment? = {
if typeName.isComponent {
return typeName.docCommentWithUserDescription(nil)
} else {
return typeName.docCommentWithUserDescription(nil, subPath: "requestBody")
}
}()
return .commentable(comment, bodyEnumDecl)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ extension TypesFileTranslator {
/// - typedResponse: The typed response to declare.
/// - Returns: A structure declaration.
func translateResponseInTypes(
responseKind: String = "",
takeshi-1000 marked this conversation as resolved.
Show resolved Hide resolved
typeName: TypeName,
response: TypedResponse
) throws -> Declaration {
Expand All @@ -34,10 +35,19 @@ extension TypesFileTranslator {
inParent: headersTypeName
)
let headerProperties: [PropertyBlueprint] = try headers.map { header in
try parseResponseHeaderAsProperty(for: header)
try parseResponseHeaderAsProperty(
responseKind: responseKind,
typeName: typeName,
for: header)
}
let headerStructComment: Comment? = {
let subPath = typeName.isComponent
? "headers"
: "reponses/\(responseKind)/headers"
takeshi-1000 marked this conversation as resolved.
Show resolved Hide resolved
return typeName.docCommentWithUserDescription(nil, subPath: subPath)
}()
let headersStructBlueprint: StructBlueprint = .init(
comment: nil,
comment: headerStructComment,
access: config.access,
typeName: headersTypeName,
conformances: Constants.Operation.Output.Payload.Headers.conformances,
Expand Down Expand Up @@ -76,22 +86,35 @@ extension TypesFileTranslator {
)
bodyCases.append(contentsOf: inlineTypeDecls)
}
let bodyCase: Declaration = .enumCase(
name: identifier,
kind: .nameWithAssociatedValues([
.init(type: associatedType.fullyQualifiedSwiftName)
])
let subPathForContentCase = typeName.isComponent
? "content/\(typedContent.content.contentType.lowercasedTypeAndSubtypeWithEscape)"
: "reponses/\(responseKind)/content/\(typedContent.content.contentType.lowercasedTypeAndSubtypeWithEscape)"
let bodyCase: Declaration = .commentable(
typeName.docCommentWithUserDescription(nil, subPath: subPathForContentCase),
.enumCase(
name: identifier,
kind: .nameWithAssociatedValues([
.init(type: associatedType.fullyQualifiedSwiftName)
])
)
)
bodyCases.append(bodyCase)
}
let subPathForContent = typeName.isComponent
? "content"
: "reponses/\(responseKind)/content"
let hasNoContent: Bool = bodyCases.isEmpty
let contentEnumDecl: Declaration = .enum(
isFrozen: true,
accessModifier: config.access,
name: bodyTypeName.shortSwiftName,
conformances: Constants.Operation.Body.conformances,
members: bodyCases
let contentEnumDecl: Declaration = .commentable(
typeName.docCommentWithUserDescription(nil, subPath: subPathForContent),
.enum(
isFrozen: true,
accessModifier: config.access,
name: bodyTypeName.shortSwiftName,
conformances: Constants.Operation.Body.conformances,
members: bodyCases
)
)

let contentTypeUsage = bodyTypeName.asUsage.withOptional(hasNoContent)
let contentProperty = PropertyBlueprint(
comment: .doc("Received HTTP response body"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,18 @@ extension TypesFileTranslator {
/// - header: A response parameter.
/// - Returns: A property blueprint.
func parseResponseHeaderAsProperty(
responseKind: String = "",
takeshi-1000 marked this conversation as resolved.
Show resolved Hide resolved
typeName: TypeName,
for header: TypedResponseHeader
) throws -> PropertyBlueprint {
let comment: Comment? = {
let subPath: String = typeName.isComponent
? "headers/\(header.name)"
: "reponses/\(responseKind)/headers/\(header.name)"
takeshi-1000 marked this conversation as resolved.
Show resolved Hide resolved
return typeName.docCommentWithUserDescription(nil, subPath: subPath)
}()
czechboy0 marked this conversation as resolved.
Show resolved Hide resolved
return .init(
comment: nil,
comment: comment,
originalName: header.name,
typeUsage: header.typeUsage,
default: header.header.required ? nil : .nil,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ extension TypesFileTranslator {
let responseStructDecl: Declaration?
if typedResponse.isInlined {
responseStructDecl = try translateResponseInTypes(
responseKind: responseKind.jsonPathComponent,
takeshi-1000 marked this conversation as resolved.
Show resolved Hide resolved
typeName: typedResponse.typeUsage.typeName,
response: typedResponse
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,10 @@ struct TypeName: Equatable {
precondition(components.count >= 1, "Cannot get the parent of a root type")
return .init(components: components.dropLast())
}

var isComponent: Bool {
takeshi-1000 marked this conversation as resolved.
Show resolved Hide resolved
description.contains("#/components")
czechboy0 marked this conversation as resolved.
Show resolved Hide resolved
}
}

extension TypeName: CustomStringConvertible {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,16 @@ extension TypesFileTranslator {
inParent: inputTypeName
)
}
let structDecl: Declaration = translateStructBlueprint(
.init(
comment: nil,
access: config.access,
typeName: structTypeName,
conformances: Constants.Operation.Input.conformances,
properties: structProperties
let structDecl: Declaration = .commentable(
inputTypeName.docCommentWithUserDescription(nil, subPath: "\(location.rawValue)"),
translateStructBlueprint(
.init(
comment: nil,
access: config.access,
typeName: structTypeName,
conformances: Constants.Operation.Input.conformances,
properties: structProperties
)
)
)

Expand Down
Loading