Skip to content

Commit 39f8e9e

Browse files
committed
Add support for rename within the current file
rdar://117822427
1 parent 8666f40 commit 39f8e9e

File tree

9 files changed

+1027
-2
lines changed

9 files changed

+1027
-2
lines changed

Sources/SKSupport/LineTable.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,16 @@ extension LineTable {
166166
return lineAndUTF16ColumnOf(content.utf8.index(content.startIndex, offsetBy: utf8Offset))
167167
}
168168

169+
@inlinable func lineAndUTF8ColumnOf(utf8Offset: Int) -> (line: Int, utf8Column: Int)? {
170+
guard let (line, utf16Column) = lineAndUTF16ColumnOf(utf8Offset: utf8Offset) else {
171+
return nil
172+
}
173+
guard let utf8Column = utf8ColumnAt(line: line, utf16Column: utf16Column) else {
174+
return nil
175+
}
176+
return (line, utf8Column)
177+
}
178+
169179
/// Returns UTF16 column offset at UTF8 version of logical position.
170180
///
171181
/// - parameter line: Line number (zero-based).

Sources/SourceKitD/SKDRequestArray.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@ public final class SKDRequestArray {
3636
public func append(_ value: String) {
3737
sourcekitd.api.request_array_set_string(array, -1, value)
3838
}
39+
40+
public func append(_ value: SKDRequestDictionary) {
41+
sourcekitd.api.request_array_set_value(array, -1, value.dict)
42+
}
3943
}
4044

4145
extension SKDRequestArray: CustomStringConvertible {

Sources/SourceKitD/sourcekitd_uids.swift

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,15 @@ public struct sourcekitd_keys {
1717
public let actionuid: sourcekitd_uid_t
1818
public let annotated_decl: sourcekitd_uid_t
1919
public let annotations: sourcekitd_uid_t
20+
public let argindex: sourcekitd_uid_t
2021
public let associated_usrs: sourcekitd_uid_t
2122
public let bodylength: sourcekitd_uid_t
2223
public let bodyoffset: sourcekitd_uid_t
2324
public let cancelOnSubsequentRequest: sourcekitd_uid_t
2425
public let categories: sourcekitd_uid_t
2526
public let categorizededits: sourcekitd_uid_t
27+
public let categorizedranges: sourcekitd_uid_t
28+
public let category: sourcekitd_uid_t
2629
public let column: sourcekitd_uid_t
2730
public let compilerargs: sourcekitd_uid_t
2831
public let context: sourcekitd_uid_t
@@ -33,6 +36,7 @@ public struct sourcekitd_keys {
3336
public let doc_full_as_xml: sourcekitd_uid_t
3437
public let edits: sourcekitd_uid_t
3538
public let educational_note_paths: sourcekitd_uid_t
39+
public let enablesyntaxmap: sourcekitd_uid_t
3640
public let endcolumn: sourcekitd_uid_t
3741
public let endline: sourcekitd_uid_t
3842
public let expression_length: sourcekitd_uid_t
@@ -49,6 +53,7 @@ public struct sourcekitd_keys {
4953
public let kind: sourcekitd_uid_t
5054
public let length: sourcekitd_uid_t
5155
public let line: sourcekitd_uid_t
56+
public let locations: sourcekitd_uid_t
5257
public let modulename: sourcekitd_uid_t
5358
public let name: sourcekitd_uid_t
5459
public let namelength: sourcekitd_uid_t
@@ -61,11 +66,28 @@ public struct sourcekitd_keys {
6166
public let ranges: sourcekitd_uid_t
6267
public let receivers: sourcekitd_uid_t
6368
public let refactor_actions: sourcekitd_uid_t
69+
public let renamelocations: sourcekitd_uid_t
70+
public let renameRangeBase: sourcekitd_uid_t
71+
public let renameRangeCallArgColon: sourcekitd_uid_t
72+
public let renameRangeCallArgCombined: sourcekitd_uid_t
73+
public let renameRangeCallArgLabel: sourcekitd_uid_t
74+
public let renameRangeDeclArgLabel: sourcekitd_uid_t
75+
public let renameRangeKeywordBase: sourcekitd_uid_t
76+
public let renameRangeNoncollapsibleParam: sourcekitd_uid_t
77+
public let renameRangeParam: sourcekitd_uid_t
78+
public let renameRangeSelectorArgLabel: sourcekitd_uid_t
6479
public let request: sourcekitd_uid_t
6580
public let results: sourcekitd_uid_t
6681
public let retrieve_refactor_actions: sourcekitd_uid_t
6782
public let semantic_tokens: sourcekitd_uid_t
6883
public let severity: sourcekitd_uid_t
84+
public let sourceEditKindActive: sourcekitd_uid_t
85+
public let sourceEditKindComment: sourcekitd_uid_t
86+
public let sourceEditKindInactive: sourcekitd_uid_t
87+
public let sourceEditKindMismatch: sourcekitd_uid_t
88+
public let sourceEditKindSelector: sourcekitd_uid_t
89+
public let sourceEditKindString: sourcekitd_uid_t
90+
public let sourceEditKindUnknown: sourcekitd_uid_t
6991
public let sourcefile: sourcekitd_uid_t
7092
public let sourcetext: sourcekitd_uid_t
7193
public let substructure: sourcekitd_uid_t
@@ -76,7 +98,6 @@ public struct sourcekitd_keys {
7698
public let syntacticRenameUnknown: sourcekitd_uid_t
7799
public let syntaxmap: sourcekitd_uid_t
78100
public let synthesizedextensions: sourcekitd_uid_t
79-
public let enablesyntaxmap: sourcekitd_uid_t
80101
public let text: sourcekitd_uid_t
81102
public let typename: sourcekitd_uid_t
82103
public let usr: sourcekitd_uid_t
@@ -103,12 +124,15 @@ public struct sourcekitd_keys {
103124
actionuid = api.uid_get_from_cstr("key.actionuid")!
104125
annotated_decl = api.uid_get_from_cstr("key.annotated_decl")!
105126
annotations = api.uid_get_from_cstr("key.annotations")!
127+
argindex = api.uid_get_from_cstr("key.argindex")!
106128
associated_usrs = api.uid_get_from_cstr("key.associated_usrs")!
107129
bodylength = api.uid_get_from_cstr("key.bodylength")!
108130
bodyoffset = api.uid_get_from_cstr("key.bodyoffset")!
109131
cancelOnSubsequentRequest = api.uid_get_from_cstr("key.cancel_on_subsequent_request")!
110132
categories = api.uid_get_from_cstr("key.categories")!
133+
category = api.uid_get_from_cstr("key.category")!
111134
categorizededits = api.uid_get_from_cstr("key.categorizededits")!
135+
categorizedranges = api.uid_get_from_cstr("key.categorizedranges")!
112136
column = api.uid_get_from_cstr("key.column")!
113137
compilerargs = api.uid_get_from_cstr("key.compilerargs")!
114138
context = api.uid_get_from_cstr("key.context")!
@@ -136,6 +160,7 @@ public struct sourcekitd_keys {
136160
kind = api.uid_get_from_cstr("key.kind")!
137161
length = api.uid_get_from_cstr("key.length")!
138162
line = api.uid_get_from_cstr("key.line")!
163+
locations = api.uid_get_from_cstr("key.locations")!
139164
modulename = api.uid_get_from_cstr("key.modulename")!
140165
name = api.uid_get_from_cstr("key.name")!
141166
namelength = api.uid_get_from_cstr("key.namelength")!
@@ -148,11 +173,28 @@ public struct sourcekitd_keys {
148173
ranges = api.uid_get_from_cstr("key.ranges")!
149174
receivers = api.uid_get_from_cstr("key.receivers")!
150175
refactor_actions = api.uid_get_from_cstr("key.refactor_actions")!
176+
renamelocations = api.uid_get_from_cstr("key.renamelocations")!
177+
renameRangeBase = api.uid_get_from_cstr("source.refactoring.range.kind.basename")!
178+
renameRangeCallArgColon = api.uid_get_from_cstr("source.refactoring.range.kind.call-argument-colon")!
179+
renameRangeCallArgCombined = api.uid_get_from_cstr("source.refactoring.range.kind.call-argument-combined")!
180+
renameRangeCallArgLabel = api.uid_get_from_cstr("source.refactoring.range.kind.call-argument-label")!
181+
renameRangeDeclArgLabel = api.uid_get_from_cstr("source.refactoring.range.kind.decl-argument-label")!
182+
renameRangeKeywordBase = api.uid_get_from_cstr("source.refactoring.range.kind.keyword-basename")!
183+
renameRangeNoncollapsibleParam = api.uid_get_from_cstr("source.refactoring.range.kind.noncollapsible-parameter")!
184+
renameRangeParam = api.uid_get_from_cstr("source.refactoring.range.kind.parameter-and-whitespace")!
185+
renameRangeSelectorArgLabel = api.uid_get_from_cstr("source.refactoring.range.kind.selector-argument-label")!
151186
request = api.uid_get_from_cstr("key.request")!
152187
results = api.uid_get_from_cstr("key.results")!
153188
retrieve_refactor_actions = api.uid_get_from_cstr("key.retrieve_refactor_actions")!
154189
semantic_tokens = api.uid_get_from_cstr("key.semantic_tokens")!
155190
severity = api.uid_get_from_cstr("key.severity")!
191+
sourceEditKindActive = api.uid_get_from_cstr("source.edit.kind.active")!
192+
sourceEditKindComment = api.uid_get_from_cstr("source.edit.kind.comment")!
193+
sourceEditKindInactive = api.uid_get_from_cstr("source.edit.kind.inactive")!
194+
sourceEditKindMismatch = api.uid_get_from_cstr("source.edit.kind.mismatch")!
195+
sourceEditKindSelector = api.uid_get_from_cstr("source.edit.kind.selector")!
196+
sourceEditKindString = api.uid_get_from_cstr("source.edit.kind.string")!
197+
sourceEditKindUnknown = api.uid_get_from_cstr("source.edit.kind.unknown")!
156198
sourcefile = api.uid_get_from_cstr("key.sourcefile")!
157199
sourcetext = api.uid_get_from_cstr("key.sourcetext")!
158200
substructure = api.uid_get_from_cstr("key.substructure")!
@@ -204,6 +246,7 @@ public struct sourcekitd_requests {
204246
public let variable_type: sourcekitd_uid_t
205247
public let relatedidents: sourcekitd_uid_t
206248
public let semantic_refactoring: sourcekitd_uid_t
249+
public let find_syntactic_rename_ranges: sourcekitd_uid_t
207250

208251
public init(api: sourcekitd_functions_t) {
209252
crash_exit = api.uid_get_from_cstr("source.request.crash_exit")!
@@ -223,6 +266,7 @@ public struct sourcekitd_requests {
223266
variable_type = api.uid_get_from_cstr("source.request.variable.type")!
224267
relatedidents = api.uid_get_from_cstr("source.request.relatedidents")!
225268
semantic_refactoring = api.uid_get_from_cstr("source.request.semantic.refactoring")!
269+
find_syntactic_rename_ranges = api.uid_get_from_cstr("source.request.find-syntactic-rename-ranges")!
226270
}
227271
}
228272

Sources/SourceKitLSP/Clang/ClangLanguageServer.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -597,6 +597,10 @@ extension ClangLanguageServerShim {
597597
func executeCommand(_ req: ExecuteCommandRequest) async throws -> LSPAny? {
598598
return try await forwardRequestToClangd(req)
599599
}
600+
601+
func rename(_ request: RenameRequest) async throws -> WorkspaceEdit? {
602+
return try await forwardRequestToClangd(request)
603+
}
600604
}
601605

602606
/// Clang build settings derived from a `FileBuildSettingsChange`.

Sources/SourceKitLSP/SourceKitServer.swift

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,10 @@ fileprivate enum TaskMetadata: DependencyTracker {
308308
self = .freestanding
309309
case is PollIndexRequest:
310310
self = .globalConfigurationChange
311+
case is RenameRequest:
312+
// Rename might touch multiple files. Make it a global configuration change so that edits to all files that might
313+
// be affected have been processed.
314+
self = .globalConfigurationChange
311315
case is RegisterCapabilityRequest:
312316
self = .globalConfigurationChange
313317
case is ShowMessageRequest:
@@ -339,7 +343,7 @@ fileprivate enum TaskMetadata: DependencyTracker {
339343
default:
340344
logger.error(
341345
"""
342-
Unknown request \(type(of: request)). Treating as a freestanding notification. \
346+
Unknown request \(type(of: request)). Treating as a freestanding request. \
343347
This might lead to out-of-order request handling
344348
"""
345349
)
@@ -851,6 +855,8 @@ extension SourceKitServer: MessageHandler {
851855
await request.reply { try await supertypes(request.params) }
852856
case let request as RequestAndReply<TypeHierarchySubtypesRequest>:
853857
await request.reply { try await subtypes(request.params) }
858+
case let request as RequestAndReply<RenameRequest>:
859+
await request.reply { try await rename(request.params) }
854860
case let request as RequestAndReply<CompletionRequest>:
855861
await self.handleRequest(for: request, requestHandler: self.completion)
856862
case let request as RequestAndReply<HoverRequest>:
@@ -1645,6 +1651,17 @@ extension SourceKitServer {
16451651
return try await languageService.executeCommand(executeCommand)
16461652
}
16471653

1654+
func rename(_ request: RenameRequest) async throws -> WorkspaceEdit? {
1655+
let uri = request.textDocument.uri
1656+
guard let workspace = await workspaceForDocument(uri: uri) else {
1657+
throw ResponseError.workspaceNotOpen(uri)
1658+
}
1659+
guard let languageService = workspace.documentService[uri] else {
1660+
return nil
1661+
}
1662+
return try await languageService.rename(request)
1663+
}
1664+
16481665
func codeAction(
16491666
_ req: CodeActionRequest,
16501667
workspace: Workspace,

Sources/SourceKitLSP/Swift/RelatedIdentifiers.swift

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,19 @@ extension RelatedIdentifier.Usage {
5555
return nil
5656
}
5757
}
58+
59+
func uid(keys: sourcekitd_keys) -> sourcekitd_uid_t {
60+
switch self {
61+
case .definition:
62+
return keys.syntacticRenameDefinition
63+
case .reference:
64+
return keys.syntacticRenameReference
65+
case .call:
66+
return keys.syntacticRenameCall
67+
case .unknown:
68+
return keys.syntacticRenameUnknown
69+
}
70+
}
5871
}
5972

6073
struct RelatedIdentifiersResponse {

0 commit comments

Comments
 (0)