@@ -26,11 +26,17 @@ public struct DeclNameLocation: Equatable {
2626 /// ## Examples
2727 /// - `a` in `func foo(a: Int) {}`
2828 /// - `a` and `b` in `func foo(a b: Int) {}`
29+ /// - `additionalTrailingClosure:` in `foo {} additionalTrailingClosure: {}`
30+ /// - We cannot use `labeledCall` here because when changing the parameter label to `_`, we need to change the
31+ /// call to `foo {} _: {}`. If we used `labeledCall`, the label would be removed, leaving us with `foo {} {}`.
2932 case labeled( firstName: Range < AbsolutePosition > , secondName: Range < AbsolutePosition > ? )
3033
3134 /// The argument of a call.
3235 ///
33- /// The range of the label does not include trivia. The range of the colon *does* include trivia.
36+ /// The range of the label does not include trivia.
37+ ///
38+ /// The range of the colon *does* include trivia. This is so we can remove the colon including the space after it
39+ /// when changing a labeled parameter to an unlabeled parameter.
3440 ///
3541 /// ## Examples
3642 /// - `a` and `:` in `foo(a: 1)`
@@ -46,10 +52,6 @@ public struct DeclNameLocation: Equatable {
4652 }
4753
4854 static func labeledCall( label: TokenSyntax , colon: TokenSyntax ) -> Argument {
49- // FIXME: (NameMatcher) The `labeledCall` case is problematic for two reasons
50- // 1. The fact that `colon` includes trivia is inconsistent with the associated values in `label` and `labeledCall`
51- // 2. If `colon` didn't need to contain trivia, we wouldn't need the `labeledCall` case at all.
52- // See if we can unify `labeledCall` and `labeled`.
5355 return . labeledCall( label: label. rangeWithoutTrivia, colon: colon. position..< colon. endPosition)
5456 }
5557
@@ -68,6 +70,18 @@ public struct DeclNameLocation: Equatable {
6870 return argumentPosition..< argumentPosition
6971 }
7072 }
73+
74+ /// Shift the ranges `utf8Offset` bytes to the right, ie. add `utf8Offset` to the upper and lower bound.
75+ func advanced( by utf8Offset: Int ) -> DeclNameLocation . Argument {
76+ switch self {
77+ case . labeled( firstName: let firstName, secondName: let secondName) :
78+ return . labeled( firstName: firstName. advanced ( by: utf8Offset) , secondName: secondName? . advanced ( by: utf8Offset) )
79+ case . labeledCall( label: let label, colon: let colon) :
80+ return . labeledCall( label: label. advanced ( by: utf8Offset) , colon: colon. advanced ( by: utf8Offset) )
81+ case . unlabeled( argumentPosition: let argumentPosition) :
82+ return . unlabeled( argumentPosition: argumentPosition. advanced ( by: utf8Offset) )
83+ }
84+ }
7185 }
7286
7387 /// The arguments of a ``DeclNameLocation``.
@@ -92,6 +106,22 @@ public struct DeclNameLocation: Equatable {
92106
93107 /// The argument label to disambiguate multiple functions with the same base name, like `foo(a:)`.
94108 case selector( [ Argument ] )
109+
110+ /// Shift the ranges `utf8Offset` bytes to the right, ie. add `utf8Offset` to the upper and lower bound.
111+ func advanced( by utf8Offset: Int ) -> DeclNameLocation . Arguments {
112+ switch self {
113+ case . noArguments:
114+ return . noArguments
115+ case . call( let arguments, firstTrailingClosureIndex: let firstTrailingClosureIndex) :
116+ return . call( arguments. map { $0. advanced ( by: utf8Offset) } , firstTrailingClosureIndex: firstTrailingClosureIndex)
117+ case . parameters( let parameters) :
118+ return . parameters( parameters. map { $0. advanced ( by: utf8Offset) } )
119+ case . noncollapsibleParameters( let parameters) :
120+ return . noncollapsibleParameters( parameters. map { $0. advanced ( by: utf8Offset) } )
121+ case . selector( let arguments) :
122+ return . selector( arguments. map { $0. advanced ( by: utf8Offset) } )
123+ }
124+ }
95125 }
96126
97127 public enum Context {
0 commit comments