Hi Swift Community :)
Playing around with SwiftSyntax, I'm trying to remove public modifier from methods and variable declarations.
But was facing an issue where considering the following implementation
public class PublicModifierExtensionRewriter: SyntaxRewriter {
override public func visit(_ node: FunctionDeclSyntax) -> DeclSyntax {
guard let modifiers = node.modifiers else { return node }
guard let extDecl = searchExtensionDeclParent(node: node), extDecl.isPublicExtension else {
print("Is NOT declared on a public extension, so we don't need to remove")
return node
}
if let publicModifier = modifiers.first(where: { $0.name.tokenKind == .publicKeyword }) {
return node.withModifiers(modifiers.removing(childAt: publicModifier.indexInParent))
}
return node
}
}
// Finding the Extension Decl parent.
fileprivate func searchExtensionDeclParent(node: Syntax?) -> ExtensionDeclSyntax? {
guard let node = node else { return nil }
if let extensionDecl = node.parent as? ExtensionDeclSyntax {
return extensionDecl
} else {
return searchExtensionDeclParent(node: node.parent)
}
}
And the following test file
public extension Int {
public func f() -> Int {
return self * self
}
static public func f2() {
}
public static func f3() {
}
}
The actual result was
public extension Int {func f() -> Int {
return self * self
}
static func f2() {
}static func f3() {
}
}
The problem is when the public modifier is the first modifier in FunctionDecl
it end up rewriting the modifier but losing the leadingTrivia information from the FunctionDecl. But only when the public modifier is first, as you can notice on the example func f2()
is fine because there is a static
modifier before public
. Also, tried instead of removing the modifier replacing with SyntaxFactory.makeBlankFunctionDecl()
but the result was the same.
I know is very simple, but I'm not sure if its a bug on the rewriter or I'm missing something on the implementation.
I've end-up with a workaround by storing the leadingTrivia info from the original FunctionDecl
and if the public modifier is the first, instead of removing it, just replace it with a ModifierDecl
created whit the leadingTrivia. See here
I'm just curious to know if anyone also encounters that or something related and if there's a better way to do this or this is a bug.
Thank's in advance for the responses :))