@@ -84,19 +84,7 @@ public struct DocumentURI: Codable, Hashable, Sendable {
84
84
}
85
85
86
86
public init ( from decoder: Decoder ) throws {
87
- let string = try decoder. singleValueContainer ( ) . decode ( String . self)
88
- guard let url = URL ( string: string) else {
89
- throw FailedToConstructDocumentURIFromStringError ( string: string)
90
- }
91
- if url. query ( ) != nil , var urlComponents = URLComponents ( string: url. absoluteString) {
92
- // See comment in `encode(to:)`
93
- urlComponents. percentEncodedQuery = urlComponents. percentEncodedQuery!. removingPercentEncoding
94
- if let rewrittenQuery = urlComponents. url {
95
- self . init ( rewrittenQuery)
96
- return
97
- }
98
- }
99
- self . init ( url)
87
+ try self . init ( string: decoder. singleValueContainer ( ) . decode ( String . self) )
100
88
}
101
89
102
90
/// Equality check to handle escape sequences in file URLs.
@@ -109,36 +97,7 @@ public struct DocumentURI: Codable, Hashable, Sendable {
109
97
hasher. combine ( self . pseudoPath)
110
98
}
111
99
112
- private static let additionalQueryEncodingCharacterSet = CharacterSet ( charactersIn: " ?=&% " ) . inverted
113
-
114
100
public func encode( to encoder: Encoder ) throws {
115
- let urlToEncode : URL
116
- if let query = storage. query ( percentEncoded: true ) , var components = URLComponents ( string: storage. absoluteString) {
117
- // The URI standard RFC 3986 is ambiguous about whether percent encoding and their represented characters are
118
- // considered equivalent. VS Code considers them equivalent and treats them the same:
119
- //
120
- // vscode.Uri.parse("x://a?b=xxxx%3Dyyyy").toString() -> 'x://a?b%3Dxxxx%3Dyyyy'
121
- // vscode.Uri.parse("x://a?b=xxxx%3Dyyyy").toString(/*skipEncoding=*/true) -> 'x://a?b=xxxx=yyyy'
122
- //
123
- // This causes issues because SourceKit-LSP's macro expansion URLs encoded by URLComponents use `=` to denote the
124
- // separation of a key and a value in the outer query. The value of the `parent` key may itself contain query
125
- // items, which use the escaped form '%3D'. Simplified, such a URL may look like
126
- // scheme://host?parent=scheme://host?line%3D2
127
- // But after running this through VS Code's URI type `=` and `%3D` get canonicalized and are indistinguishable.
128
- // To avoid this ambiguity, always percent escape the characters we use to distinguish URL query parameters,
129
- // producing the following URL.
130
- // scheme://host?parent%3Dscheme://host%3Fline%253D2
131
- components. percentEncodedQuery =
132
- query
133
- . addingPercentEncoding ( withAllowedCharacters: Self . additionalQueryEncodingCharacterSet)
134
- if let componentsUrl = components. url {
135
- urlToEncode = componentsUrl
136
- } else {
137
- urlToEncode = self . storage
138
- }
139
- } else {
140
- urlToEncode = self . storage
141
- }
142
- try urlToEncode. absoluteString. encode ( to: encoder)
101
+ try storage. absoluteString. encode ( to: encoder)
143
102
}
144
103
}
0 commit comments