From 27a43e6b02769444f12a86aa40a9de47585929a0 Mon Sep 17 00:00:00 2001 From: Krishna Permi <40313959+krishnapermi@users.noreply.github.com> Date: Fri, 3 Jul 2026 20:49:41 +0530 Subject: [PATCH 1/2] Fix findManifestTargetCall to only search top-level targets Refactor target call search to only check top-level elements in the targets array, preventing incorrect matches from nested dependencies. --- .../PackageManifest/SyntaxEditUtils.swift | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/Sources/SwiftRefactor/PackageManifest/SyntaxEditUtils.swift b/Sources/SwiftRefactor/PackageManifest/SyntaxEditUtils.swift index 2f1abdb3a0c..c5eb4ff9648 100644 --- a/Sources/SwiftRefactor/PackageManifest/SyntaxEditUtils.swift +++ b/Sources/SwiftRefactor/PackageManifest/SyntaxEditUtils.swift @@ -198,7 +198,19 @@ extension FunctionCallExprSyntax { return literalValue == targetName } - guard let targetCall = FunctionCallExprSyntax.findFirst(in: targetArray, matching: matchesTargetCall) else { + // Only check the top-level elements of the targets array. A recursive + // search would incorrectly match a target name that appears inside + // another target's `dependencies:` array — e.g. `.target(name: "Foo")` + // listed as a dependency has the same `name:` argument as the actual + // `.target(name: "Foo")` definition at the top level. + guard let targetCall = targetArray.elements.lazy.compactMap({ element -> FunctionCallExprSyntax? in + guard let call = element.expression.as(FunctionCallExprSyntax.self), + matchesTargetCall(call: call) + else { + return nil + } + return call + }).first else { throw ManifestEditError.cannotFindTarget(targetName: targetName) } From 4e369a2b78d5214f6765cd960a2eddcdc962f2f4 Mon Sep 17 00:00:00 2001 From: Krishna Permi <40313959+krishnapermi@users.noreply.github.com> Date: Fri, 3 Jul 2026 20:51:24 +0530 Subject: [PATCH 2/2] Add regression test for findManifestTargetCall Added a regression test to ensure that modifying a target's name in dependencies updates the actual target definition correctly. --- .../SwiftRefactorTest/ManifestEditTests.swift | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/Tests/SwiftRefactorTest/ManifestEditTests.swift b/Tests/SwiftRefactorTest/ManifestEditTests.swift index eb53f384f90..a24fc5275de 100644 --- a/Tests/SwiftRefactorTest/ManifestEditTests.swift +++ b/Tests/SwiftRefactorTest/ManifestEditTests.swift @@ -642,6 +642,57 @@ final class ManifestEditTests: XCTestCase { ) } + func testAddTargetDependencyWhenTargetIsAlsoDependency() throws { + // Regression test: when a target's name appears inside another target's + // dependencies array, the refactoring must modify the actual target + // definition, not the nested dependency reference. + // See https://github.com/swiftlang/swift-package-manager/issues/10122 + try assertManifestRefactor( + """ + // swift-tools-version: 5.5 + let package = Package( + name: "packages", + targets: [ + .target( + name: "Library", + dependencies: [ + .target(name: "Helper"), + ] + ), + .target( + name: "Helper" + ), + ] + ) + """, + expectedManifest: """ + // swift-tools-version: 5.5 + let package = Package( + name: "packages", + targets: [ + .target( + name: "Library", + dependencies: [ + .target(name: "Helper"), + ] + ), + .target( + name: "Helper", + dependencies: [ + .target(name: "Support"), + ] + ), + ] + ) + """, + provider: AddTargetDependency.self, + context: .init( + dependency: .target(name: "Support"), + targetName: "Helper" + ) + ) + } + func testAddJava2SwiftPlugin() throws { try assertManifestRefactor( """