Skip to content

Commit e715e93

Browse files
committed
Address Review Comments
1 parent 1939847 commit e715e93

File tree

7 files changed

+58
-90
lines changed

7 files changed

+58
-90
lines changed

Sources/SKSupport/FileSystem.swift

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -36,15 +36,3 @@ extension AbsolutePath {
3636
public var defaultDirectoryForGeneratedFiles: AbsolutePath {
3737
try! AbsolutePath(validating: NSTemporaryDirectory()).appending(component: "sourcekit-lsp")
3838
}
39-
40-
/// The default directory to write generated module interfaces
41-
/// `<TEMPORARY_DIRECTORY>/sourcekit-lsp/GeneratedInterfaces/`
42-
public var defaultDirectoryForGeneratedInterfaces: AbsolutePath {
43-
defaultDirectoryForGeneratedFiles.appending(component: "GeneratedInterfaces")
44-
}
45-
46-
/// The default directory to write generated macro expansions
47-
/// `<TEMPORARY_DIRECTORY>/sourcekit-lsp/GeneratedMacroExpansions/`
48-
public var defaultDirectoryForGeneratedMacroExpansions: AbsolutePath {
49-
defaultDirectoryForGeneratedFiles.appending(component: "GeneratedMacroExpansions")
50-
}

Sources/SourceKitLSP/Swift/MacroExpansion.swift

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ import LSPLogging
1414
import LanguageServerProtocol
1515
import SourceKitD
1616

17+
@_spi(Testing) public typealias MacroExpansionEdit = RefactoringEdit
18+
1719
/// Detailed information about the result of a macro expansion operation.
1820
///
1921
/// Wraps the information returned by sourcekitd's `semantic_refactoring`
@@ -32,17 +34,12 @@ struct MacroExpansion: RefactoringResponse {
3234
self.title = title
3335
self.uri = uri
3436
self.edits = refactoringEdits.compactMap { refactoringEdit in
35-
36-
guard let bufferName = refactoringEdit.bufferName else {
37+
if refactoringEdit.bufferName.isEmpty {
3738
logger.error("Unable to retrieve some parts of the expansion")
3839
return nil
3940
}
4041

41-
return MacroExpansionEdit(
42-
range: refactoringEdit.startPosition..<refactoringEdit.endPosition,
43-
newText: refactoringEdit.newText,
44-
bufferName: bufferName
45-
)
42+
return refactoringEdit
4643
}
4744
}
4845
}
@@ -86,9 +83,13 @@ extension SwiftLanguageService {
8683

8784
Task {
8885
let req = ShowDocumentRequest(uri: macroExpansionDocURI, selection: macroEdit.range)
89-
let response = try await sourceKitLSPServer.sendRequestToClient(req)
90-
if !response.success {
91-
logger.error("client refused to show document for \(expansion.title, privacy: .public)!")
86+
87+
let response = await orLog("Sending ShowDocumentRequest to Client") {
88+
try await sourceKitLSPServer.sendRequestToClient(req)
89+
}
90+
91+
if !(response?.success ?? true) {
92+
logger.error("client refused to show document for \(expansion.title, privacy: .public)")
9293
}
9394
}
9495
}

Sources/SourceKitLSP/Swift/RefactorCommand.swift

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,8 @@
1313
import LanguageServerProtocol
1414
import SourceKitD
1515

16-
/// A protocol to be utilised by all commands where underlies sourcekitd calls
17-
/// to perform semantic refactoring.
16+
/// A protocol to be utilised by all commands that are served by sourcekitd refactorings.
1817
protocol RefactorCommand: SwiftCommand {
19-
2018
/// The response type of the refactor command
2119
associatedtype Response: RefactoringResponse
2220

Sources/SourceKitLSP/Swift/Refactoring.swift

Lines changed: 23 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -12,52 +12,43 @@
1212

1313
import LanguageServerProtocol
1414
import SourceKitD
15+
import LSPLogging
1516

1617
protocol RefactoringResponse {
17-
1818
init(title: String, uri: DocumentURI, refactoringEdits: [RefactoringEdit])
19-
20-
/// Create an instance of `RefactoringResponse` from a sourcekitd semantic
21-
/// refactoring response dictionary, if possible. Passes the response to
22-
/// `init(title: String, uri: DocumentURI, refactoringEdits:
23-
/// [RefactoringEdit])` in a neat manner
24-
init?(_ title: String, _ dict: SKDResponseDictionary, _ snapshot: DocumentSnapshot, _ keys: sourcekitd_api_keys)
2519
}
2620

27-
typealias RefactoringEdit = (startPosition: Position, endPosition: Position, newText: String, bufferName: String?)
28-
2921
extension RefactoringResponse {
30-
31-
/// Create an instance of `RefactoringResponse` from a sourcekitd semantic
32-
/// refactoring response dictionary, if possible. Passes the response to
33-
/// `init(title: String, uri: DocumentURI, refactoringEdits:
34-
/// [RefactoringEdit])` in a neat manner
22+
/// Create an instance of `RefactoringResponse` from a sourcekitd semantic
23+
/// refactoring response dictionary, if possible.
3524
///
3625
/// - Parameters:
3726
/// - title: The title of the refactoring action.
3827
/// - dict: Response dictionary to extract information from.
39-
/// - snapshot: The snapshot that triggered the `semantic_refactoring`
40-
/// request.
28+
/// - snapshot: The snapshot that triggered the `semantic_refactoring` request.
4129
/// - keys: The sourcekitd key set to use for looking up into `dict`.
4230
init?(_ title: String, _ dict: SKDResponseDictionary, _ snapshot: DocumentSnapshot, _ keys: sourcekitd_api_keys) {
4331
guard let categorizedEdits: SKDResponseArray = dict[keys.categorizedEdits] else {
32+
logger.error("categorizedEdits doesn't exist in response dictionary")
4433
return nil
4534
}
4635

4736
var refactoringEdits = [RefactoringEdit]()
4837

49-
categorizedEdits.forEach { _, value in
50-
guard let edits: SKDResponseArray = value[keys.edits] else {
51-
return false
38+
categorizedEdits.forEach { _, categorizedEdit in
39+
guard let edits: SKDResponseArray = categorizedEdit[keys.edits] else {
40+
logger.error("edits doesn't exist in categorizedEdit dictionary")
41+
return true
5242
}
53-
edits.forEach { _, value in
43+
edits.forEach { _, edit in
5444
// The LSP is zero based, but semantic_refactoring is one based.
55-
guard let startLine: Int = value[keys.line],
56-
let startColumn: Int = value[keys.column],
57-
let endLine: Int = value[keys.endLine],
58-
let endColumn: Int = value[keys.endColumn],
59-
let text: String = value[keys.text]
45+
guard let startLine: Int = edit[keys.line],
46+
let startColumn: Int = edit[keys.column],
47+
let endLine: Int = edit[keys.endLine],
48+
let endColumn: Int = edit[keys.endColumn],
49+
let text: String = edit[keys.text]
6050
else {
51+
logger.error("Failed to deserialise edit dictionary containing values: \(edit)")
6152
return true // continue
6253
}
6354

@@ -74,17 +65,15 @@ extension RefactoringResponse {
7465
// can't be represented in the editor properly.
7566
let textWithSnippets = rewriteSourceKitPlaceholders(in: text, clientSupportsSnippets: false)
7667
refactoringEdits.append(
77-
(
78-
startPosition: startPosition, endPosition: endPosition, newText: textWithSnippets,
79-
bufferName: value[keys.bufferName]
80-
)
68+
RefactoringEdit(range: startPosition..<endPosition, newText: textWithSnippets, bufferName: edit[keys.bufferName] ?? "")
8169
)
8270
return true
8371
}
8472
return true
8573
}
8674

87-
guard refactoringEdits.isEmpty == false else {
75+
guard !refactoringEdits.isEmpty else {
76+
logger.error("No refactors found")
8877
return nil
8978
}
9079

@@ -100,13 +89,12 @@ extension SwiftLanguageService {
10089
/// request, such as the necessary edits and placeholder locations.
10190
///
10291
/// - Parameters:
103-
/// - command: The semantic `RefactorCommand` that triggered this request.
104-
/// - responseType: The response type `T.Type` of the particular command
92+
/// - refactorCommand: The semantic `RefactorCommand` that triggered this request.
10593
/// - Returns:
10694
/// - The `RefactoringResponse` as `T`
107-
func refactoring<T: RefactorCommand>(_ refactorCommand: T) async throws
108-
-> T.Response
109-
{
95+
func refactoring<T: RefactorCommand>(
96+
_ refactorCommand: T
97+
) async throws -> T.Response {
11098
let keys = self.keys
11199

112100
let uri = refactorCommand.textDocument.uri

Sources/SourceKitLSP/Swift/MacroExpansionEdit.swift renamed to Sources/SourceKitLSP/Swift/RefactoringEdit.swift

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,8 @@
1313
import LanguageServerProtocol
1414
import SourceKitD
1515

16-
/// Represents a macro expansion as an edit. Notionally, a subclass of
17-
/// `TextEdit`
18-
@_spi(Testing) public struct MacroExpansionEdit: Hashable, Sendable, Codable {
16+
/// Represents an edit from semantic refactor response. Notionally, a subclass /// of `TextEdit`
17+
@_spi(Testing) public struct RefactoringEdit: Hashable, Sendable, Codable {
1918
/// The range of text to be replaced.
2019
@CustomCodable<PositionRange>
2120
public var range: Range<Position>
@@ -32,7 +31,7 @@ import SourceKitD
3231
}
3332
}
3433

35-
extension MacroExpansionEdit: LSPAnyCodable {
34+
extension RefactoringEdit: LSPAnyCodable {
3635
public init?(fromLSPDictionary dictionary: [String: LSPAny]) {
3736
guard case .dictionary(let rangeDict) = dictionary[CodingKeys.range.stringValue],
3837
case .string(let newText) = dictionary[CodingKeys.newText.stringValue],

Sources/SourceKitLSP/Swift/SemanticRefactoring.swift

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ struct SemanticRefactoring: RefactoringResponse {
3434
init(title: String, uri: DocumentURI, refactoringEdits: [RefactoringEdit]) {
3535
self.title = title
3636
self.edit = WorkspaceEdit(changes: [
37-
uri: refactoringEdits.map { TextEdit(range: $0.startPosition..<$0.endPosition, newText: $0.newText) }
37+
uri: refactoringEdits.map { TextEdit(range: $0.range, newText: $0.newText) }
3838
])
3939
}
4040
}
@@ -68,8 +68,7 @@ extension SwiftLanguageService {
6868
/// side for the actual refactoring.
6969
///
7070
/// - Parameters:
71-
/// - semanticRefactorCommand: The `SemanticRefactorCommand` that triggered
72-
/// this request.
71+
/// - semanticRefactorCommand: The `SemanticRefactorCommand` that triggered this request.
7372
///
7473
/// - Returns:
7574
/// - a `WorkspaceEdit` with the necessary refactors as a `LSPAny`
@@ -94,7 +93,7 @@ extension SwiftLanguageService {
9493
} else {
9594
reason = ""
9695
}
97-
logger.error("client refused to apply edit for \(semanticRefactor.title, privacy: .public)!\(reason)")
96+
logger.error("client refused to apply edit for \(semanticRefactor.title, privacy: .public) \(reason)")
9897
}
9998

10099
return edit.encodeToLSPAny()

Tests/SourceKitLSPTests/ExecuteCommandTests.swift

Lines changed: 17 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import LSPTestSupport
1414
import LanguageServerProtocol
1515
import SKTestSupport
1616
import XCTest
17+
import SwiftExtensions
1718
@_spi(Testing) import SourceKitLSP
1819

1920
final class ExecuteCommandTests: XCTestCase {
@@ -182,18 +183,16 @@ final class ExecuteCommandTests: XCTestCase {
182183

183184
let (uri, positions) = try project.openDocument("MyMacroClient.swift")
184185

185-
let argsToBeTested = [
186-
ExpandMacroCommand(
187-
positionRange: positions["1️⃣"]..<positions["3️⃣"],
188-
textDocument: TextDocumentIdentifier(uri)
189-
),
190-
ExpandMacroCommand(
191-
positionRange: positions["2️⃣"]..<positions["3️⃣"],
192-
textDocument: TextDocumentIdentifier(uri)
193-
),
186+
let positionMarkersToBeTested = [
187+
(start: "1️⃣", end: "1️⃣"),
188+
(start: "2️⃣", end: "2️⃣"),
189+
(start: "1️⃣", end: "3️⃣"),
190+
(start: "2️⃣", end: "3️⃣"),
194191
]
195192

196-
for args in argsToBeTested {
193+
for positionMarker in positionMarkersToBeTested {
194+
let args = ExpandMacroCommand(positionRange: positions[positionMarker.start]..<positions[positionMarker.end], textDocument: TextDocumentIdentifier(uri))
195+
197196
let metadata = SourceKitLSPCommandMetadata(textDocument: TextDocumentIdentifier(uri))
198197

199198
var command = args.asCommand()
@@ -202,35 +201,31 @@ final class ExecuteCommandTests: XCTestCase {
202201
let request = ExecuteCommandRequest(command: command.command, arguments: command.arguments)
203202

204203
let expectation = XCTestExpectation(description: "Handle Show Document Request")
205-
var showDocumentRequestURI: DocumentURI? = nil
204+
let showDocumentRequestURI = ThreadSafeBox<DocumentURI?>(initialValue: nil)
206205

207206
project.testClient.handleSingleRequest { (req: ShowDocumentRequest) in
208-
showDocumentRequestURI = req.uri
207+
showDocumentRequestURI.value = req.uri
209208
expectation.fulfill()
210209
return ShowDocumentResponse(success: true)
211210
}
212211

213212
let result = try await project.testClient.send(request)
214213

215214
guard let resultArray: [MacroExpansionEdit] = Array(fromLSPArray: result ?? .null) else {
216-
XCTFail("Result is not an array.")
215+
XCTFail("Result is not an array. Failed for position range between \(positionMarker.start) and \(positionMarker.end)")
217216
return
218217
}
219218

220-
XCTAssertEqual(resultArray.count, 1)
221-
XCTAssertEqual(resultArray.only?.newText, "(1 + 2, \"1 + 2\")")
219+
XCTAssertEqual(resultArray.count, 1, "resultArray is empty. Failed for position range between \(positionMarker.start) and \(positionMarker.end)")
220+
XCTAssertEqual(resultArray.only?.newText, "(1 + 2, \"1 + 2\")", "Wrong macro expansion. Failed for position range between \(positionMarker.start) and \(positionMarker.end)")
222221

223222
await fulfillment(of: [expectation], timeout: 10.0)
224223

225-
let url = try XCTUnwrap(showDocumentRequestURI?.fileURL)
226-
227-
XCTAssert(
228-
(try? url.checkResourceIsReachable()) ?? false
229-
)
224+
let url = try XCTUnwrap(showDocumentRequestURI.value?.fileURL, "Failed for position range between \(positionMarker.start) and \(positionMarker.end)")
230225

231-
let fileContents = try XCTUnwrap(try? String(contentsOf: url, encoding: .utf8))
226+
let fileContents = try String(contentsOf: url, encoding: .utf8)
232227

233-
XCTAssert(fileContents.contains("(1 + 2, \"1 + 2\")"))
228+
XCTAssert(fileContents.contains("(1 + 2, \"1 + 2\")"), "File doesn't contain macro expansion. Failed for position range between \(positionMarker.start) and \(positionMarker.end)")
234229
}
235230
}
236231

0 commit comments

Comments
 (0)