Skip to content

Commit f40f610

Browse files
authored
Merge pull request #282 from benlangmuir/sourcekitd-sharing
[sourcekitd] Add support for having multiple notification handlers with correct sharing
2 parents 8b57352 + 0670fb5 commit f40f610

28 files changed

+1347
-809
lines changed

Package.swift

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,12 @@ let package = Package(
3434
.target(
3535
name: "SourceKit",
3636
dependencies: [
37-
"Csourcekitd",
3837
"BuildServerProtocol",
3938
"IndexStoreDB",
4039
"LanguageServerProtocol",
4140
"LanguageServerProtocolJSONRPC",
4241
"SKCore",
42+
"SourceKitD",
4343
"SKSwiftPMWorkspace",
4444
"SwiftToolsSupport-auto",
4545
]
@@ -85,17 +85,12 @@ let package = Package(
8585
]
8686
),
8787

88-
// Csourcekitd: C modules wrapper for sourcekitd.
89-
.target(
90-
name: "Csourcekitd",
91-
dependencies: []
92-
),
93-
9488
// SKCore: Data structures and algorithms useful across the project, but not necessarily
9589
// suitable for use in other packages.
9690
.target(
9791
name: "SKCore",
9892
dependencies: [
93+
"SourceKitD",
9994
"BuildServerProtocol",
10095
"LanguageServerProtocol",
10196
"LanguageServerProtocolJSONRPC",
@@ -111,6 +106,30 @@ let package = Package(
111106
]
112107
),
113108

109+
// SourceKitD: Swift bindings for sourcekitd.
110+
.target(
111+
name: "SourceKitD",
112+
dependencies: [
113+
"Csourcekitd",
114+
"LSPLogging",
115+
"SKSupport",
116+
"SwiftToolsSupport-auto",
117+
]
118+
),
119+
.testTarget(
120+
name: "SourceKitDTests",
121+
dependencies: [
122+
"SourceKitD",
123+
"SKCore",
124+
]
125+
),
126+
127+
// Csourcekitd: C modules wrapper for sourcekitd.
128+
.target(
129+
name: "Csourcekitd",
130+
dependencies: []
131+
),
132+
114133
// Logging support used in LSP modules.
115134
.target(
116135
name: "LSPLogging",

Sources/Csourcekitd/include/module.modulemap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
module sourcekitd {
1+
module Csourcekitd {
22
// header "sourcekitd.h"
33
header "sourcekitd_functions.h"
44
export *

Sources/SourceKit/sourcekitd/CursorInfo.swift renamed to Sources/SourceKit/Swift/CursorInfo.swift

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
import LanguageServerProtocol
1414
import TSCBasic
15-
import sourcekitd
15+
import SourceKitD
1616

1717
/// Detailed information about a symbol under the cursor.
1818
///
@@ -76,7 +76,7 @@ extension SwiftLanguageServer {
7676
func _cursorInfo(
7777
_ uri: DocumentURI,
7878
_ range: Range<Position>,
79-
additionalParameters appendAdditionalParameters: ((SKRequestDictionary) -> Void)? = nil,
79+
additionalParameters appendAdditionalParameters: ((SKDRequestDictionary) -> Void)? = nil,
8080
_ completion: @escaping (Swift.Result<CursorInfo?, CursorInfoError>) -> Void)
8181
{
8282
guard let snapshot = documentManager.latestSnapshot(uri) else {
@@ -89,7 +89,7 @@ extension SwiftLanguageServer {
8989

9090
let keys = self.keys
9191

92-
let skreq = SKRequestDictionary(sourcekitd: sourcekitd)
92+
let skreq = SKDRequestDictionary(sourcekitd: sourcekitd)
9393
skreq[keys.request] = requests.cursorinfo
9494
skreq[keys.offset] = offsetRange.lowerBound
9595
if offsetRange.upperBound != offsetRange.lowerBound {
@@ -107,7 +107,7 @@ extension SwiftLanguageServer {
107107
let handle = self.sourcekitd.send(skreq, self.queue) { [weak self] result in
108108
guard let self = self else { return }
109109
guard let dict = result.success else {
110-
return completion(.failure(.responseError(result.failure!)))
110+
return completion(.failure(.responseError(ResponseError(result.failure!))))
111111
}
112112

113113
guard let _: sourcekitd_uid_t = dict[keys.kind] else {
@@ -123,7 +123,7 @@ extension SwiftLanguageServer {
123123
location = Location(uri: DocumentURI(URL(fileURLWithPath: filepath)), range: Range(pos))
124124
}
125125

126-
let refactorActionsArray: SKResponseArray? = dict[keys.refactor_actions]
126+
let refactorActionsArray: SKDResponseArray? = dict[keys.refactor_actions]
127127

128128
completion(.success(
129129
CursorInfo(
@@ -140,7 +140,7 @@ extension SwiftLanguageServer {
140140
range: range,
141141
textDocument: TextDocumentIdentifier(uri),
142142
keys,
143-
self.api)
143+
self.sourcekitd.api)
144144
)))
145145
}
146146

@@ -160,7 +160,7 @@ extension SwiftLanguageServer {
160160
func cursorInfo(
161161
_ uri: DocumentURI,
162162
_ range: Range<Position>,
163-
additionalParameters appendAdditionalParameters: ((SKRequestDictionary) -> Void)? = nil,
163+
additionalParameters appendAdditionalParameters: ((SKDRequestDictionary) -> Void)? = nil,
164164
_ completion: @escaping (Swift.Result<CursorInfo?, CursorInfoError>) -> Void)
165165
{
166166
self.queue.async {

Sources/SourceKit/sourcekitd/Diagnostic.swift renamed to Sources/SourceKit/Swift/Diagnostic.swift

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,14 @@
1313
import LanguageServerProtocol
1414
import LSPLogging
1515
import SKSupport
16-
import sourcekitd
16+
import SourceKitD
1717

1818
extension CodeAction {
1919

2020
/// Creates a CodeAction from a list for sourcekit fixits.
2121
///
2222
/// If this is from a note, the note's description should be passed as `fromNote`.
23-
init?(fixits: SKResponseArray, in snapshot: DocumentSnapshot, fromNote: String?) {
23+
init?(fixits: SKDResponseArray, in snapshot: DocumentSnapshot, fromNote: String?) {
2424
var edits: [TextEdit] = []
2525
let editsMapped = fixits.forEach { (_, skfixit) -> Bool in
2626
if let edit = TextEdit(fixit: skfixit, in: snapshot) {
@@ -88,7 +88,7 @@ extension CodeAction {
8888
extension TextEdit {
8989

9090
/// Creates a TextEdit from a sourcekitd fixit response dictionary.
91-
init?(fixit: SKResponseDictionary, in snapshot: DocumentSnapshot) {
91+
init?(fixit: SKDResponseDictionary, in snapshot: DocumentSnapshot) {
9292
let keys = fixit.sourcekitd.keys
9393
if let utf8Offset: Int = fixit[keys.offset],
9494
let length: Int = fixit[keys.length],
@@ -107,7 +107,7 @@ extension TextEdit {
107107
extension Diagnostic {
108108

109109
/// Creates a diagnostic from a sourcekitd response dictionary.
110-
init?(_ diag: SKResponseDictionary, in snapshot: DocumentSnapshot) {
110+
init?(_ diag: SKDResponseDictionary, in snapshot: DocumentSnapshot) {
111111
// FIXME: this assumes that the diagnostics are all in the same file.
112112

113113
let keys = diag.sourcekitd.keys
@@ -142,13 +142,13 @@ extension Diagnostic {
142142
}
143143

144144
var actions: [CodeAction]? = nil
145-
if let skfixits: SKResponseArray = diag[keys.fixits],
145+
if let skfixits: SKDResponseArray = diag[keys.fixits],
146146
let action = CodeAction(fixits: skfixits, in: snapshot, fromNote: nil) {
147147
actions = [action]
148148
}
149149

150150
var notes: [DiagnosticRelatedInformation]? = nil
151-
if let sknotes: SKResponseArray = diag[keys.diagnostics] {
151+
if let sknotes: SKDResponseArray = diag[keys.diagnostics] {
152152
notes = []
153153
sknotes.forEach { (_, sknote) -> Bool in
154154
guard let note = DiagnosticRelatedInformation(sknote, in: snapshot) else { return true }
@@ -171,7 +171,7 @@ extension Diagnostic {
171171
extension DiagnosticRelatedInformation {
172172

173173
/// Creates related information from a sourcekitd note response dictionary.
174-
init?(_ diag: SKResponseDictionary, in snapshot: DocumentSnapshot) {
174+
init?(_ diag: SKDResponseDictionary, in snapshot: DocumentSnapshot) {
175175
let keys = diag.sourcekitd.keys
176176

177177
var position: Position? = nil
@@ -191,7 +191,7 @@ extension DiagnosticRelatedInformation {
191191
guard let message: String = diag[keys.description] else { return nil }
192192

193193
var actions: [CodeAction]? = nil
194-
if let skfixits: SKResponseArray = diag[keys.fixits],
194+
if let skfixits: SKDResponseArray = diag[keys.fixits],
195195
let action = CodeAction(fixits: skfixits, in: snapshot, fromNote: message) {
196196
actions = [action]
197197
}
@@ -209,7 +209,7 @@ struct CachedDiagnostic {
209209
}
210210

211211
extension CachedDiagnostic {
212-
init?(_ diag: SKResponseDictionary, in snapshot: DocumentSnapshot) {
212+
init?(_ diag: SKDResponseDictionary, in snapshot: DocumentSnapshot) {
213213
let sk = diag.sourcekitd
214214
guard let diagnostic = Diagnostic(diag, in: snapshot) else { return nil }
215215
self.diagnostic = diagnostic
@@ -243,7 +243,7 @@ enum DiagnosticStage: Hashable {
243243
}
244244

245245
extension DiagnosticStage {
246-
init?(_ uid: sourcekitd_uid_t, sourcekitd: SwiftSourceKitFramework) {
246+
init?(_ uid: sourcekitd_uid_t, sourcekitd: SourceKitD) {
247247
switch uid {
248248
case sourcekitd.values.diag_stage_parse:
249249
self = .parse

Sources/SourceKit/sourcekitd/SemanticRefactorCommand.swift renamed to Sources/SourceKit/Swift/SemanticRefactorCommand.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212
import LanguageServerProtocol
13-
import sourcekitd
13+
import SourceKitD
1414

1515
public struct SemanticRefactorCommand: SwiftCommand {
1616

@@ -64,7 +64,7 @@ public struct SemanticRefactorCommand: SwiftCommand {
6464
}
6565

6666
extension Array where Element == SemanticRefactorCommand {
67-
init?(array: SKResponseArray?, range: Range<Position>, textDocument: TextDocumentIdentifier, _ keys: sourcekitd_keys, _ api: sourcekitd_functions_t) {
67+
init?(array: SKDResponseArray?, range: Range<Position>, textDocument: TextDocumentIdentifier, _ keys: sourcekitd_keys, _ api: sourcekitd_functions_t) {
6868
guard let results = array else {
6969
return nil
7070
}

Sources/SourceKit/sourcekitd/SemanticRefactoring.swift renamed to Sources/SourceKit/Swift/SemanticRefactoring.swift

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
//===----------------------------------------------------------------------===//
1212
import LanguageServerProtocol
1313
import TSCBasic
14-
import sourcekitd
14+
import SourceKitD
1515

1616
/// Detailed information about the result of a specific refactoring operation.
1717
///
@@ -36,15 +36,15 @@ struct SemanticRefactoring {
3636
/// - dict: Response dictionary to extract information from.
3737
/// - url: The client URL that triggered the `semantic_refactoring` request.
3838
/// - keys: The sourcekitd key set to use for looking up into `dict`.
39-
init?(_ title: String, _ dict: SKResponseDictionary, _ snapshot: DocumentSnapshot, _ keys: sourcekitd_keys) {
40-
guard let categorizedEdits: SKResponseArray = dict[keys.categorizededits] else {
39+
init?(_ title: String, _ dict: SKDResponseDictionary, _ snapshot: DocumentSnapshot, _ keys: sourcekitd_keys) {
40+
guard let categorizedEdits: SKDResponseArray = dict[keys.categorizededits] else {
4141
return nil
4242
}
4343

4444
var textEdits = [TextEdit]()
4545

4646
categorizedEdits.forEach { _, value in
47-
guard let edits: SKResponseArray = value[keys.edits] else {
47+
guard let edits: SKDResponseArray = value[keys.edits] else {
4848
return false
4949
}
5050
edits.forEach { _, value in
@@ -142,7 +142,7 @@ extension SwiftLanguageServer {
142142
return completion(.failure(.invalidRange(refactorCommand.positionRange)))
143143
}
144144

145-
let skreq = SKRequestDictionary(sourcekitd: self.sourcekitd)
145+
let skreq = SKDRequestDictionary(sourcekitd: self.sourcekitd)
146146
skreq[keys.request] = self.requests.semantic_refactoring
147147
// Preferred name for e.g. an extracted variable.
148148
// Empty string means sourcekitd chooses a name automatically.
@@ -162,7 +162,7 @@ extension SwiftLanguageServer {
162162
let handle = self.sourcekitd.send(skreq, self.queue) { [weak self] result in
163163
guard let self = self else { return }
164164
guard let dict = result.success else {
165-
return completion(.failure(.responseError(result.failure!)))
165+
return completion(.failure(.responseError(ResponseError(result.failure!))))
166166
}
167167
guard let refactor = SemanticRefactoring(refactorCommand.title, dict, snapshot, self.keys) else {
168168
return completion(.failure(.noEditsNeeded(uri)))
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
import SourceKitD
14+
import LanguageServerProtocol
15+
16+
extension ResponseError {
17+
public init(_ value: SKDError) {
18+
switch value {
19+
case .requestCancelled:
20+
self = .cancelled
21+
case .requestFailed(let desc):
22+
self = .unknown("sourcekitd request failed: \(desc)")
23+
case .requestInvalid(let desc):
24+
self = .unknown("sourcekitd invalid request \(desc)")
25+
case .missingRequiredSymbol(let desc):
26+
self = .unknown("sourcekitd missing required symbol '\(desc)'")
27+
case .connectionInterrupted:
28+
self = .unknown("sourcekitd connection interrupted")
29+
}
30+
}
31+
}

0 commit comments

Comments
 (0)