Skip to content

Commit

Permalink
Refactor syntax node manipulation to use variable setters
Browse files Browse the repository at this point in the history
This commit replaces the use of 'with' method for syntax node manipulation in SwiftSyntax examples with direct variable setters for better clarity and readability.
  • Loading branch information
Matejkob committed Oct 12, 2023
1 parent fc58fc8 commit 15d205f
Show file tree
Hide file tree
Showing 8 changed files with 84 additions and 105 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ private class AddOneToIntegerLiterals: SyntaxRewriter {
let int = Int(integerText)!

// Create a new integer literal token with `int + 1` as its text.
let newIntegerLiteralToken = token.with(\.tokenKind, .integerLiteral("\(int + 1)"))
var newIntegerLiteralToken = token
newIntegerLiteralToken.tokenKind = .integerLiteral("\(int + 1)")

// Return the new integer literal.
return newIntegerLiteralToken
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,7 @@ extension DictionaryStorageMacro: MemberMacro {
providingMembersOf declaration: some DeclGroupSyntax,
in context: some MacroExpansionContext
) throws -> [DeclSyntax] {
let storage: DeclSyntax = "var _storage: [String: Any] = [:]"
return [
storage.with(\.leadingTrivia, [.newlines(1), .spaces(2)])
]
return ["\n var _storage: [String: Any] = [:]"]
}
}

Expand All @@ -43,11 +40,11 @@ extension DictionaryStorageMacro: MemberAttributeMacro {

return [
AttributeSyntax(
leadingTrivia: [.newlines(1), .spaces(2)],
attributeName: IdentifierTypeSyntax(
name: .identifier("DictionaryStorageProperty")
)
)
.with(\.leadingTrivia, [.newlines(1), .spaces(2)])
]
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public struct AddBlocker: ExpressionMacro {
_ node: InfixOperatorExprSyntax
) -> ExprSyntax {
// Identify any infix operator + in the tree.
if let binOp = node.operator.as(BinaryOperatorExprSyntax.self) {
if var binOp = node.operator.as(BinaryOperatorExprSyntax.self) {
if binOp.operator.text == "+" {
// Form the warning
let messageID = MessageID(domain: "silly", id: "addblock")
Expand Down Expand Up @@ -72,17 +72,9 @@ public struct AddBlocker: ExpressionMacro {
)
)

return ExprSyntax(
node.with(
\.operator,
ExprSyntax(
binOp.with(
\.operator,
binOp.operator.with(\.tokenKind, .binaryOperator("-"))
)
)
)
)
binOp.operator.tokenKind = .binaryOperator("-")

return ExprSyntax(node.with(\.operator, ExprSyntax(binOp)))
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,12 @@ private func replaceFirstLabel(
of tuple: LabeledExprListSyntax,
with newLabel: String
) -> LabeledExprListSyntax {
guard let firstElement = tuple.first else {
if tuple.isEmpty {
return tuple
}

var tuple = tuple
tuple[tuple.startIndex] =
firstElement
.with(\.label, .identifier(newLabel))
.with(\.colon, .colonToken())
tuple[tuple.startIndex].label = .identifier(newLabel)
tuple[tuple.startIndex].colon = .colonToken()
return tuple
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,11 @@ public struct WrapStoredPropertiesMacro: MemberAttributeMacro {

return [
AttributeSyntax(
leadingTrivia: [.newlines(1), .spaces(2)],
attributeName: IdentifierTypeSyntax(
name: .identifier(wrapperName.content.text)
)
)
.with(\.leadingTrivia, [.newlines(1), .spaces(2)])
]
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public struct AddAsyncMacro: PeerMacro {
) throws -> [DeclSyntax] {

// Only on functions at the moment.
guard let funcDecl = declaration.as(FunctionDeclSyntax.self) else {
guard var funcDecl = declaration.as(FunctionDeclSyntax.self) else {
throw CustomError.message("@addAsync only works on functions")
}

Expand All @@ -42,7 +42,7 @@ public struct AddAsyncMacro: PeerMacro {
}

// This only makes sense void functions
if funcDecl.signature.returnClause?.type.with(\.leadingTrivia, []).with(\.trailingTrivia, []).description != "Void" {
if funcDecl.signature.returnClause?.type.as(IdentifierTypeSyntax.self)?.name.text != "Void" {
throw CustomError.message(
"@addAsync requires an function that returns void"
)
Expand All @@ -58,7 +58,7 @@ public struct AddAsyncMacro: PeerMacro {
}

// Completion handler needs to return Void
if completionHandlerParameter.returnClause.type.with(\.leadingTrivia, []).with(\.trailingTrivia, []).description != "Void" {
if completionHandlerParameter.returnClause.type.as(IdentifierTypeSyntax.self)?.name.text != "Void" {
throw CustomError.message(
"@addAsync requires an function that has a completion handler that returns Void"
)
Expand All @@ -72,9 +72,11 @@ public struct AddAsyncMacro: PeerMacro {
// Remove completionHandler and comma from the previous parameter
var newParameterList = funcDecl.signature.parameterClause.parameters
newParameterList.removeLast()
let newParameterListLastParameter = newParameterList.last!
var newParameterListLastParameter = newParameterList.last!
newParameterList.removeLast()
newParameterList.append(newParameterListLastParameter.with(\.trailingTrivia, []).with(\.trailingComma, nil))
newParameterListLastParameter.trailingTrivia = []
newParameterListLastParameter.trailingComma = nil
newParameterList.append(newParameterListLastParameter)

// Drop the @addAsync attribute from the new declaration.
let newAttributeList = funcDecl.attributes.filter {
Expand Down Expand Up @@ -121,42 +123,36 @@ public struct AddAsyncMacro: PeerMacro {
"""

let newFunc =
funcDecl
.with(
\.signature,
funcDecl.signature
.with(
\.effectSpecifiers,
FunctionEffectSpecifiersSyntax(
leadingTrivia: .space,
asyncSpecifier: .keyword(.async),
throwsSpecifier: isResultReturn ? .keyword(.throws) : nil
) // add async
)
.with(
\.returnClause,
successReturnType != nil ? ReturnClauseSyntax(leadingTrivia: .space, type: successReturnType!.with(\.leadingTrivia, .space)) : nil
) // add result type
.with(
\.parameterClause,
funcDecl.signature.parameterClause.with(\.parameters, newParameterList) // drop completion handler
.with(\.trailingTrivia, [])
)
)
.with(
\.body,
CodeBlockSyntax(
leftBrace: .leftBraceToken(leadingTrivia: .space),
statements: CodeBlockItemListSyntax(
[CodeBlockItemSyntax(item: .expr(newBody))]
),
rightBrace: .rightBraceToken(leadingTrivia: .newline)
)
)
.with(\.attributes, newAttributeList)
.with(\.leadingTrivia, .newlines(2))
// add async
funcDecl.signature.effectSpecifiers = FunctionEffectSpecifiersSyntax(
leadingTrivia: .space,
asyncSpecifier: .keyword(.async),
throwsSpecifier: isResultReturn ? .keyword(.throws) : nil
)

// add result type
if let successReturnType {
funcDecl.signature.returnClause = ReturnClauseSyntax(leadingTrivia: .space, type: successReturnType.with(\.leadingTrivia, .space))
} else {
funcDecl.signature.returnClause = nil
}

// drop completion handler
funcDecl.signature.parameterClause.parameters = newParameterList
funcDecl.signature.parameterClause.trailingTrivia = []

funcDecl.body = CodeBlockSyntax(
leftBrace: .leftBraceToken(leadingTrivia: .space),
statements: CodeBlockItemListSyntax(
[CodeBlockItemSyntax(item: .expr(newBody))]
),
rightBrace: .rightBraceToken(leadingTrivia: .newline)
)

funcDecl.attributes = newAttributeList

funcDecl.leadingTrivia = .newlines(2)

return [DeclSyntax(newFunc)]
return [DeclSyntax(funcDecl)]
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,20 +25,22 @@ public struct AddCompletionHandlerMacro: PeerMacro {
) throws -> [DeclSyntax] {
// Only on functions at the moment. We could handle initializers as well
// with a bit of work.
guard let funcDecl = declaration.as(FunctionDeclSyntax.self) else {
guard var funcDecl = declaration.as(FunctionDeclSyntax.self) else {
throw CustomError.message("@addCompletionHandler only works on functions")
}

// This only makes sense for async functions.
if funcDecl.signature.effectSpecifiers?.asyncSpecifier == nil {
let newEffects: FunctionEffectSpecifiersSyntax
var newEffects: FunctionEffectSpecifiersSyntax
if let existingEffects = funcDecl.signature.effectSpecifiers {
newEffects = existingEffects.with(\.asyncSpecifier, .keyword(.async))
newEffects = existingEffects
newEffects.asyncSpecifier = .keyword(.async)
} else {
newEffects = FunctionEffectSpecifiersSyntax(asyncSpecifier: .keyword(.async))
}

let newSignature = funcDecl.signature.with(\.effectSpecifiers, newEffects)
var newSignature = funcDecl.signature
newSignature.effectSpecifiers = newEffects
let messageID = MessageID(domain: "MacroExamples", id: "MissingAsync")

let diag = Diagnostic(
Expand Down Expand Up @@ -73,7 +75,9 @@ public struct AddCompletionHandlerMacro: PeerMacro {
}

// Form the completion handler parameter.
let resultType: TypeSyntax? = funcDecl.signature.returnClause?.type.with(\.leadingTrivia, []).with(\.trailingTrivia, [])
var resultType = funcDecl.signature.returnClause?.type
resultType?.leadingTrivia = []
resultType?.trailingTrivia = []

let completionHandlerParam =
FunctionParameterSyntax(
Expand All @@ -85,14 +89,12 @@ public struct AddCompletionHandlerMacro: PeerMacro {
// Add the completion handler parameter to the parameter list.
let parameterList = funcDecl.signature.parameterClause.parameters
var newParameterList = parameterList
if let lastParam = parameterList.last {
if var lastParam = parameterList.last {
// We need to add a trailing comma to the preceding list.
newParameterList.removeLast()
lastParam.trailingComma = .commaToken(trailingTrivia: .space)
newParameterList += [
lastParam.with(
\.trailingComma,
.commaToken(trailingTrivia: .space)
),
lastParam,
completionHandlerParam,
]
} else {
Expand Down Expand Up @@ -136,35 +138,28 @@ public struct AddCompletionHandlerMacro: PeerMacro {
return attributeType.name.text != nodeType.name.text
}

let newFunc =
funcDecl
.with(
\.signature,
funcDecl.signature
.with(
\.effectSpecifiers,
funcDecl.signature.effectSpecifiers?.with(\.asyncSpecifier, nil) // drop async
)
.with(\.returnClause, nil) // drop result type
.with(
\.parameterClause, // add completion handler parameter
funcDecl.signature.parameterClause.with(\.parameters, newParameterList)
.with(\.trailingTrivia, [])
)
)
.with(
\.body,
CodeBlockSyntax(
leftBrace: .leftBraceToken(leadingTrivia: .space),
statements: CodeBlockItemListSyntax(
[CodeBlockItemSyntax(item: .expr(newBody))]
),
rightBrace: .rightBraceToken(leadingTrivia: .newline)
)
)
.with(\.attributes, newAttributeList)
.with(\.leadingTrivia, .newlines(2))
// drop async
funcDecl.signature.effectSpecifiers?.asyncSpecifier = nil

// drop result type
funcDecl.signature.returnClause = nil

// add completion handler parameter
funcDecl.signature.parameterClause.parameters = newParameterList
funcDecl.signature.parameterClause.trailingTrivia = []

funcDecl.body = CodeBlockSyntax(
leftBrace: .leftBraceToken(leadingTrivia: .space),
statements: CodeBlockItemListSyntax(
[CodeBlockItemSyntax(item: .expr(newBody))]
),
rightBrace: .rightBraceToken(leadingTrivia: .newline)
)

funcDecl.attributes = newAttributeList

funcDecl.leadingTrivia = .newlines(2)

return [DeclSyntax(newFunc)]
return [DeclSyntax(funcDecl)]
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ func runPeerMacrosPlayground() {
var value = 0
}

let counter = Counter()
_ = Counter()

// print("Peer value with suffix name for \(Counter.self): \(String(describing: Counter_peer))")
}

0 comments on commit 15d205f

Please sign in to comment.