Skip to content

Commit

Permalink
correct the removeUnusedArguments rewriter
Browse files Browse the repository at this point in the history
  • Loading branch information
MahdiBM committed Jul 15, 2024
1 parent 53fb16a commit fa7dac5
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 45 deletions.
106 changes: 62 additions & 44 deletions Sources/EnumeratorMacroImpl/Rewriter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@ final class Rewriter: SyntaxRewriter {
/// to:
/// ```swift
/// switch self {
/// case .testCase(x):
/// case .testCase(x, _):
/// return x
/// ```
/// so it removes `y` because `y` is unused.
/// so it replaces `y` with `_` because `y` is unused.
private func removeUnusedArguments(_ node: SwitchCaseSyntax) -> SwitchCaseSyntax {
guard let label = node.label.as(SwitchCaseLabelSyntax.self) else {
return node
Expand All @@ -36,59 +36,77 @@ final class Rewriter: SyntaxRewriter {
continue
}

var missingPresenceIndices: [Int] = []
for (idx, argument) in functionCallSyntax.arguments.enumerated() {
var arguments = functionCallSyntax.arguments
var didModify = false
var allArgsAreWildcards = true

for (idx, argument) in arguments.enumerated() {
guard let patternExpr = argument.expression.as(PatternExprSyntax.self),
let identifier = patternExpr.pattern.as(IdentifierPatternSyntax.self) else {
continue
}
let presenceDetector = PresenceDetector(toDetect: identifier.identifier.tokenKind)
presenceDetector.walk(node)
if presenceDetector.detectCount < 2 {
missingPresenceIndices.append(idx)
/// The arg is already a wildcard so no need to modify
if identifier.identifier.tokenKind == .wildcard {
allArgsAreWildcards = allArgsAreWildcards && true
continue
} else {
let presenceDetector = PresenceDetector(toDetect: identifier.identifier.tokenKind)
presenceDetector.walk(node)
if presenceDetector.detectCount < 2 {
didModify = true
allArgsAreWildcards = allArgsAreWildcards && true
let idx = arguments.index(at: idx)
arguments[idx] = arguments[idx].with(
\.expression,
ExprSyntax(
patternExpr.with(
\.pattern,
PatternSyntax(
identifier.with(
\.identifier,
.wildcardToken()
)
)
)
)
)
} else {
allArgsAreWildcards = false
}
}
}

var arguments = functionCallSyntax.arguments

for (index, idxInArguments) in missingPresenceIndices.enumerated() {
let idx = arguments.index(at: idxInArguments - index)
arguments.remove(at: idx)
}
let innerExpression: ExprSyntax

if !missingPresenceIndices.isEmpty {
let innerExpression: ExprSyntax = if arguments.isEmpty {
functionCallSyntax.calledExpression
} else {
ExprSyntax(
functionCallSyntax.with(
\.arguments,
arguments.with(
/// Remove the trailing comma from the last arg, if it's there.
\.[arguments.lastIndex(where: { _ in true })!],
arguments.last!.with(
\.trailingComma,
nil
)
)
)
switch (didModify, allArgsAreWildcards) {
case (true, true), (false, true):
innerExpression = functionCallSyntax.calledExpression
case (true, false):
innerExpression = ExprSyntax(
functionCallSyntax.with(
\.arguments,
arguments
)
}
items = items.with(
\.[items.index(at: idx)].pattern,
PatternSyntax(
pattern.with(
\.pattern,
PatternSyntax(
expr.with(
\.expression,
innerExpression
)
)
)
)
)
case (false, false):
/// Nothing to modify
continue
}

items = items.with(
\.[items.index(at: idx)].pattern,
PatternSyntax(
pattern.with(
\.pattern,
PatternSyntax(
expr.with(
\.expression,
innerExpression
)
)
)
)
)
}

let node = node.with(
Expand Down
2 changes: 1 addition & 1 deletion Tests/EnumeratorMacroTests/EnumeratorMacroTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -635,7 +635,7 @@ final class EnumeratorMacroTests: XCTestCase {
var isTestCase: Bool {
switch self {
case let .a(x):
case let .a(x, _):
return x
default:
return false
Expand Down

0 comments on commit fa7dac5

Please sign in to comment.