Skip to content

Use self for member access/assignment in all initializers, decoders, and encoders #700

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

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
Original file line number Diff line number Diff line change
Expand Up @@ -1354,6 +1354,16 @@ extension Expression {
/// - Returns: A new expression representing member access with a dot prefix.
static func dot(_ member: String) -> Self { Self.memberAccess(.init(right: member)) }

/// Returns a new member access expression with `self` as the receiver.
///
/// For example: `self.foo`, where `member` is `foo`.
///
/// - Parameter member: The name of the member to access on the expression.
/// - Returns: A new expression representing member access.
static func selfDot(_ member: String) -> Expression {
.memberAccess(.init(left: .identifier(.pattern("self")), right: member))
}

/// Returns a new identifier expression for the provided pattern, such
/// as a variable or function name.
/// - Parameter name: The name of the identifier.
Expand Down Expand Up @@ -1555,6 +1565,7 @@ extension Expression {
/// - Parameter expressions: The member expressions.
/// - Returns: A tuple expression.
static func tuple(_ expressions: [Expression]) -> Self { .tuple(.init(members: expressions)) }

}

extension MemberAccessDescription {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ extension FileTranslator {
let assignExprs: [Expression] = properties.map { property in
let typeUsage = property.typeUsage
return .assignment(
left: .identifierPattern("self").dot(property.swiftSafeName),
left: .selfDot(property.swiftSafeName),
right: .try(
.identifierPattern("container").dot("decode\(typeUsage.isOptional ? "IfPresent" : "")")
.call([
Expand Down Expand Up @@ -156,7 +156,7 @@ extension FileTranslator {
.try(
.identifierPattern("container").dot("encode\(property.typeUsage.isOptional ? "IfPresent" : "")")
.call([
.init(label: nil, expression: .identifierPattern("self").dot(property.swiftSafeName)),
.init(label: nil, expression: .selfDot(property.swiftSafeName)),
.init(label: "forKey", expression: .dot(property.swiftSafeName)),
])
)
Expand All @@ -181,7 +181,7 @@ extension FileTranslator {
let assignExprs: [Expression] = properties.map { property, isKeyValuePair in
let decoderExpr: Expression =
isKeyValuePair ? .initFromDecoderExpr() : .decodeFromSingleValueContainerExpr()
return .assignment(left: .identifierPattern(property.swiftSafeName), right: .try(decoderExpr))
return .assignment(left: .selfDot(property.swiftSafeName), right: .try(decoderExpr))
}
return decoderInitializer(body: assignExprs.map { .expression($0) })
}
Expand All @@ -194,12 +194,11 @@ extension FileTranslator {
{
let exprs: [Expression]
if let firstSingleValue = properties.first(where: { !$0.isKeyValuePair }) {
let expr: Expression = .identifierPattern(firstSingleValue.property.swiftSafeName)
let expr: Expression = .selfDot(firstSingleValue.property.swiftSafeName)
.encodeToSingleValueContainerExpr(gracefully: false)
exprs = [expr]
} else {
exprs = properties.filter { $0.isKeyValuePair }.map(\.property.swiftSafeName)
.map { name in .identifierPattern(name).encodeExpr() }
exprs = properties.filter(\.isKeyValuePair).map { .selfDot($0.property.swiftSafeName).encodeExpr() }
}
return encoderFunction(body: exprs.map { .expression($0) })
}
Expand All @@ -216,18 +215,15 @@ extension FileTranslator {
let assignBlocks: [CodeBlock] = properties.map { (property, isKeyValuePair) in
let decoderExpr: Expression =
isKeyValuePair ? .initFromDecoderExpr() : .decodeFromSingleValueContainerExpr()
let assignExpr: Expression = .assignment(
left: .identifierPattern(property.swiftSafeName),
right: .try(decoderExpr)
)
let assignExpr: Expression = .assignment(left: .selfDot(property.swiftSafeName), right: .try(decoderExpr))
return .expression(assignExpr.wrapInDoCatchAppendArrayExpr())
}
let atLeastOneNotNilCheckExpr: Expression = .try(
.identifierType(TypeName.decodingError).dot("verifyAtLeastOneSchemaIsNotNil")
.call([
.init(
label: nil,
expression: .literal(.array(properties.map { .identifierPattern($0.property.swiftSafeName) }))
expression: .literal(.array(properties.map { .selfDot($0.property.swiftSafeName) }))
), .init(label: "type", expression: .identifierPattern("Self").dot("self")),
.init(label: "codingPath", expression: .identifierPattern("decoder").dot("codingPath")),
.init(label: "errors", expression: .identifierPattern("errors")),
Expand All @@ -250,14 +246,12 @@ extension FileTranslator {
? nil
: .try(
.identifierPattern("encoder").dot("encodeFirstNonNilValueToSingleValueContainer")
.call([
.init(label: nil, expression: .literal(.array(singleValueNames.map { .identifierPattern($0) })))
])
.call([.init(label: nil, expression: .literal(.array(singleValueNames.map { .selfDot($0) })))])
)
let encodeExprs: [Expression] =
(encodeSingleValuesExpr.flatMap { [$0] } ?? [])
+ properties.filter { $0.isKeyValuePair }.map(\.property)
.map { property in .identifierPattern(property.swiftSafeName).optionallyChained().encodeExpr() }
.map { property in .selfDot(property.swiftSafeName).optionallyChained().encodeExpr() }
return encoderFunction(body: encodeExprs.map { .expression($0) })
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,10 +107,8 @@ extension TypesFileTranslator {
case .variable(var variableDescription) = commented
else { return member }
let name = TextBasedRenderer.renderedExpressionAsString(variableDescription.left)
variableDescription.getter = [.expression(.identifierPattern("storage").dot("value").dot(name))]
variableDescription.modify = [
.expression(.yield(.inOut(.identifierPattern("storage").dot("value").dot(name))))
]
variableDescription.getter = [.expression(.selfDot("storage").dot("value").dot(name))]
variableDescription.modify = [.expression(.yield(.inOut(.selfDot("storage").dot("value").dot(name))))]
return .commentable(comment, .variable(variableDescription))
}

Expand All @@ -127,7 +125,7 @@ extension TypesFileTranslator {
funcDesc.body = [
.expression(
.assignment(
left: .identifierPattern("storage"),
left: .selfDot("storage"),
right: .dot("init")
.call([
.init(
Expand Down Expand Up @@ -167,7 +165,7 @@ extension TypesFileTranslator {
body: [
.expression(
.assignment(
left: .identifierPattern("storage"),
left: .selfDot("storage"),
right: .try(
.dot("init").call([.init(label: "from", expression: .identifierPattern("decoder"))])
)
Expand All @@ -185,7 +183,7 @@ extension TypesFileTranslator {
body: [
.expression(
.try(
.identifierPattern("storage").dot("encode")
.selfDot("storage").dot("encode")
.call([.init(label: "to", expression: .identifierPattern("encoder"))])
)
)
Expand Down
Loading
Loading