diff --git a/Sources/SwiftIDEUtils/DeclNameLocation.swift b/Sources/SwiftIDEUtils/DeclNameLocation.swift index d6b352717a6..b7c5c886755 100644 --- a/Sources/SwiftIDEUtils/DeclNameLocation.swift +++ b/Sources/SwiftIDEUtils/DeclNameLocation.swift @@ -102,6 +102,12 @@ public struct DeclNameLocation: Equatable { /// The parameter of a function declaration, like `func foo(a b: Int)` case parameters([Argument]) + /// An enum case declaration like `case myCase(label: String)`. + /// + /// For enum case parameters the argument label is removed when set to empty instead of being changed to eg. + /// `myCase(_ label: String)` + case enumCaseParameters([Argument]) + /// Same as `param` but the parameters can't be collapsed if they are the same. This is the case for subscript /// declarations. /// @@ -123,6 +129,8 @@ public struct DeclNameLocation: Equatable { ) case .parameters(let parameters): return .parameters(parameters.map { $0.advanced(by: utf8Offset) }) + case .enumCaseParameters(let parameters): + return .enumCaseParameters(parameters.map { $0.advanced(by: utf8Offset) }) case .noncollapsibleParameters(let parameters): return .noncollapsibleParameters(parameters.map { $0.advanced(by: utf8Offset) }) case .selector(let arguments): diff --git a/Sources/SwiftIDEUtils/NameMatcher.swift b/Sources/SwiftIDEUtils/NameMatcher.swift index d1991b2770c..c868831bd37 100644 --- a/Sources/SwiftIDEUtils/NameMatcher.swift +++ b/Sources/SwiftIDEUtils/NameMatcher.swift @@ -298,7 +298,7 @@ public class NameMatcher: SyntaxAnyVisitor { return .unlabeled(argument: Syntax(argument.secondName) ?? Syntax(argument.colon) ?? Syntax(argument.type)) } } - addResolvedLocIfRequested(baseName: node.name, argumentLabels: .parameters(argumentLabels)) + addResolvedLocIfRequested(baseName: node.name, argumentLabels: .enumCaseParameters(argumentLabels)) } return .visitChildren } diff --git a/Tests/SwiftIDEUtilsTest/NameMatcherTests.swift b/Tests/SwiftIDEUtilsTest/NameMatcherTests.swift index b21399783b3..8383c1a25db 100644 --- a/Tests/SwiftIDEUtilsTest/NameMatcherTests.swift +++ b/Tests/SwiftIDEUtilsTest/NameMatcherTests.swift @@ -51,6 +51,7 @@ private func assertNameMatcherResult( case .noArguments: argumentLabels = [] case .call(let labels, _): argumentLabels = labels case .parameters(let labels): argumentLabels = labels + case .enumCaseParameters(let labels): argumentLabels = labels case .noncollapsibleParameters(let labels): argumentLabels = labels case .selector(let labels): argumentLabels = labels } @@ -75,6 +76,7 @@ private struct DeclNameLocationSpec { case noArguments case call case parameters + case enumCaseParameters case noncollapsibleParameters case selector @@ -83,6 +85,7 @@ private struct DeclNameLocationSpec { case .noArguments: self = .noArguments case .call: self = .call case .parameters: self = .parameters + case .enumCaseParameters: self = .enumCaseParameters case .noncollapsibleParameters: self = .noncollapsibleParameters case .selector: self = .selector } @@ -326,4 +329,56 @@ class NameMatcherTests: XCTestCase { ] ) } + + func testEnumCaseParameterWithLabels() { + assertNameMatcherResult( + """ + enum MyEnum { + case 1️⃣myCase(label: String) + } + """, + expected: [ + DeclNameLocationSpec(baseName: "myCase", argumentLabels: ["label"], type: .enumCaseParameters) + ] + ) + } + + func testEnumCaseParameterWithoutLabels() { + assertNameMatcherResult( + """ + enum MyEnum { + case 1️⃣myCase(String) + } + """, + expected: [ + DeclNameLocationSpec(baseName: "myCase", argumentLabels: [""], type: .enumCaseParameters) + ] + ) + } + + func testEnumCaseParameterWithoutAssociatedValues() { + assertNameMatcherResult( + """ + enum MyEnum { + case 1️⃣myCase + } + """, + expected: [ + DeclNameLocationSpec(baseName: "myCase", argumentLabels: [], type: .noArguments) + ] + ) + } + + func testEnumCaseParameterWithoutWildcardAsExternalLabel() { + assertNameMatcherResult( + """ + enum MyEnum { + case 1️⃣myCase(_ label: String) + } + """, + expected: [ + DeclNameLocationSpec(baseName: "myCase", argumentLabels: ["_ label"], type: .enumCaseParameters) + ] + ) + } }