Skip to content

Commit 8f9fb53

Browse files
authored
Merge pull request #831 from ahoppen/ahoppen/clean-up-build-system
Clean up `BuildSystemManager`
2 parents a79893a + d7a454a commit 8f9fb53

9 files changed

+17
-272
lines changed

Sources/SKCore/BuildServerBuildSystem.swift

Lines changed: 16 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -43,14 +43,15 @@ func executable(_ name: String) -> String {
4343
///
4444
/// Provides build settings from a build server launched based on a
4545
/// `buildServer.json` configuration file provided in the repo root.
46-
public final class BuildServerBuildSystem {
46+
public final class BuildServerBuildSystem: MessageHandler {
47+
/// The handler's request queue. `delegate` will always be called on this queue.
48+
public let queue: DispatchQueue = DispatchQueue(label: "language-server-queue", qos: .userInitiated)
4749

4850
let projectRoot: AbsolutePath
4951
let buildFolder: AbsolutePath?
5052
let serverConfig: BuildServerConfig
5153
let requestQueue: DispatchQueue
5254

53-
var handler: BuildServerHandler?
5455
var buildServer: JSONRPCConnection?
5556

5657
let searchPaths: [AbsolutePath]
@@ -62,10 +63,7 @@ public final class BuildServerBuildSystem {
6263
public var indexPrefixMappings: [PathPrefixMapping] { return [] }
6364

6465
/// Delegate to handle any build system events.
65-
public weak var delegate: BuildSystemDelegate? {
66-
get { return self.handler?.delegate }
67-
set { self.handler?.delegate = newValue }
68-
}
66+
public weak var delegate: BuildSystemDelegate?
6967

7068
public init(projectRoot: AbsolutePath, buildFolder: AbsolutePath?, fileSystem: FileSystem = localFileSystem) throws {
7169
let configPath = projectRoot.appending(component: "buildServer.json")
@@ -146,8 +144,7 @@ public final class BuildServerBuildSystem {
146144
rootUri: URI(self.projectRoot.asURL),
147145
capabilities: BuildClientCapabilities(languageIds: languages))
148146

149-
let handler = BuildServerHandler()
150-
let buildServer = try makeJSONRPCBuildServer(client: handler, serverPath: serverPath, serverFlags: flags)
147+
let buildServer = try makeJSONRPCBuildServer(client: self, serverPath: serverPath, serverFlags: flags)
151148
let response = try buildServer.sendSync(initializeRequest)
152149
buildServer.send(InitializedBuildNotification())
153150
log("initialized build server \(response.displayName)")
@@ -160,34 +157,13 @@ public final class BuildServerBuildSystem {
160157
self.indexStorePath = try AbsolutePath(validating: indexStorePath, relativeTo: self.projectRoot)
161158
}
162159
self.buildServer = buildServer
163-
self.handler = handler
164-
}
165-
}
166-
167-
private func readReponseDataKey(data: LSPAny?, key: String) -> String? {
168-
if case .dictionary(let dataDict)? = data,
169-
case .string(let stringVal)? = dataDict[key] {
170-
return stringVal
171160
}
172161

173-
return nil
174-
}
175-
176-
/// A handler that receives messages from the build server.
177-
///
178-
/// In practice, it listens for updated build settings and informs the
179-
/// ``BuildSystemDelegate`` about these changes.
180-
final class BuildServerHandler: MessageHandler {
181-
/// The handler's request queue. `delegate` will always be called on this queue.
182-
public let queue: DispatchQueue = DispatchQueue(label: "language-server-queue", qos: .userInitiated)
183-
184-
public weak var delegate: BuildSystemDelegate? = nil
185-
186162
/// Handler for notifications received **from** the builder server, ie.
187163
/// the build server has sent us a notification.
188164
///
189165
/// We need to notify the delegate about any updated build settings.
190-
func handle(_ params: some NotificationType, from clientID: ObjectIdentifier) {
166+
public func handle(_ params: some NotificationType, from clientID: ObjectIdentifier) {
191167
queue.async {
192168
if let params = params as? BuildTargetsChangedNotification {
193169
self.handleBuildTargetsChanged(Notification(params, clientID: clientID))
@@ -200,7 +176,7 @@ final class BuildServerHandler: MessageHandler {
200176
/// Handler for requests received **from** the build server.
201177
///
202178
/// We currently can't handle any requests sent from the build server to us.
203-
func handle<R: RequestType>(
179+
public func handle<R: RequestType>(
204180
_ params: R,
205181
id: RequestID,
206182
from clientID: ObjectIdentifier,
@@ -223,6 +199,15 @@ final class BuildServerHandler: MessageHandler {
223199
}
224200
}
225201

202+
private func readReponseDataKey(data: LSPAny?, key: String) -> String? {
203+
if case .dictionary(let dataDict)? = data,
204+
case .string(let stringVal)? = dataDict[key] {
205+
return stringVal
206+
}
207+
208+
return nil
209+
}
210+
226211
extension BuildServerBuildSystem {
227212
/// Exposed for *testing*.
228213
public func _settings(for uri: DocumentURI) -> FileBuildSettings? {
@@ -261,41 +246,6 @@ extension BuildServerBuildSystem: BuildSystem {
261246
})
262247
}
263248

264-
public func buildTargets(reply: @escaping (LSPResult<[BuildTarget]>) -> Void) {
265-
_ = self.buildServer?.send(BuildTargets(), queue: requestQueue) { response in
266-
switch response {
267-
case .success(let result):
268-
reply(.success(result.targets))
269-
case .failure(let error):
270-
reply(.failure(error))
271-
}
272-
}
273-
}
274-
275-
public func buildTargetSources(targets: [BuildTargetIdentifier], reply: @escaping (LSPResult<[SourcesItem]>) -> Void) {
276-
let req = BuildTargetSources(targets: targets)
277-
_ = self.buildServer?.send(req, queue: requestQueue) { response in
278-
switch response {
279-
case .success(let result):
280-
reply(.success(result.items))
281-
case .failure(let error):
282-
reply(.failure(error))
283-
}
284-
}
285-
}
286-
287-
public func buildTargetOutputPaths(targets: [BuildTargetIdentifier], reply: @escaping (LSPResult<[OutputsItem]>) -> Void) {
288-
let req = BuildTargetOutputPaths(targets: targets)
289-
_ = self.buildServer?.send(req, queue: requestQueue) { response in
290-
switch response {
291-
case .success(let result):
292-
reply(.success(result.items))
293-
case .failure(let error):
294-
reply(.failure(error))
295-
}
296-
}
297-
}
298-
299249
public func filesDidChange(_ events: [FileEvent]) {}
300250

301251
public func fileHandlingCapability(for uri: DocumentURI) -> FileHandlingCapability {

Sources/SKCore/BuildSystem.swift

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -63,19 +63,6 @@ public protocol BuildSystem: AnyObject {
6363
/// such as command line flag changes, dependency changes, etc.
6464
func unregisterForChangeNotifications(for: DocumentURI)
6565

66-
/// Returns the build targets in the workspace. If the build system does not
67-
/// support build targets the `buildTargetsNotSupported` error should be
68-
/// returned.
69-
func buildTargets(reply: @escaping (LSPResult<[BuildTarget]>) -> Void)
70-
71-
/// Returns the sources for the requested build targets
72-
func buildTargetSources(targets: [BuildTargetIdentifier],
73-
reply: @escaping (LSPResult<[SourcesItem]>) -> Void)
74-
75-
/// Returns the output paths for the requested build targets
76-
func buildTargetOutputPaths(targets: [BuildTargetIdentifier],
77-
reply: @escaping (LSPResult<[OutputsItem]>) -> Void)
78-
7966
/// Called when files in the project change.
8067
func filesDidChange(_ events: [FileEvent])
8168

Sources/SKCore/BuildSystemManager.swift

Lines changed: 1 addition & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -135,14 +135,7 @@ public final class BuildSystemManager {
135135
}
136136
}
137137

138-
extension BuildSystemManager: BuildSystem {
139-
140-
public var indexStorePath: AbsolutePath? { queue.sync { buildSystem?.indexStorePath } }
141-
142-
public var indexDatabasePath: AbsolutePath? { queue.sync { buildSystem?.indexDatabasePath } }
143-
144-
public var indexPrefixMappings: [PathPrefixMapping] { queue.sync { buildSystem?.indexPrefixMappings ?? [] } }
145-
138+
extension BuildSystemManager {
146139
public var delegate: BuildSystemDelegate? {
147140
get { queue.sync { _delegate } }
148141
set { queue.sync { _delegate = newValue } }
@@ -319,42 +312,6 @@ extension BuildSystemManager: BuildSystem {
319312
}
320313
}
321314

322-
public func buildTargets(reply: @escaping (LSPResult<[BuildTarget]>) -> Void) {
323-
queue.async {
324-
if let buildSystem = self.buildSystem {
325-
buildSystem.buildTargets(reply: reply)
326-
} else {
327-
reply(.success([]))
328-
}
329-
}
330-
}
331-
332-
public func buildTargetSources(
333-
targets: [BuildTargetIdentifier],
334-
reply: @escaping (LSPResult<[SourcesItem]>) -> Void)
335-
{
336-
queue.async {
337-
if let buildSystem = self.buildSystem {
338-
buildSystem.buildTargetSources(targets: targets, reply: reply)
339-
} else {
340-
reply(.success([]))
341-
}
342-
}
343-
}
344-
345-
public func buildTargetOutputPaths(
346-
targets: [BuildTargetIdentifier],
347-
reply: @escaping (LSPResult<[OutputsItem]>) -> Void)
348-
{
349-
queue.async {
350-
if let buildSystem = self.buildSystem {
351-
buildSystem.buildTargetOutputPaths(targets: targets, reply: reply)
352-
} else {
353-
reply(.success([]))
354-
}
355-
}
356-
}
357-
358315
public func fileHandlingCapability(for uri: DocumentURI) -> FileHandlingCapability {
359316
return max(buildSystem?.fileHandlingCapability(for: uri) ?? .unhandled, fallbackBuildSystem?.fileHandlingCapability(for: uri) ?? .unhandled)
360317
}

Sources/SKCore/CompilationDatabaseBuildSystem.swift

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -111,18 +111,6 @@ extension CompilationDatabaseBuildSystem: BuildSystem {
111111
}
112112
}
113113

114-
public func buildTargets(reply: @escaping (LSPResult<[BuildTarget]>) -> Void) {
115-
reply(.failure(buildTargetsNotSupported))
116-
}
117-
118-
public func buildTargetSources(targets: [BuildTargetIdentifier], reply: @escaping (LSPResult<[SourcesItem]>) -> Void) {
119-
reply(.failure(buildTargetsNotSupported))
120-
}
121-
122-
public func buildTargetOutputPaths(targets: [BuildTargetIdentifier], reply: @escaping (LSPResult<[OutputsItem]>) -> Void) {
123-
reply(.failure(buildTargetsNotSupported))
124-
}
125-
126114
/// Must be invoked on `queue`.
127115
private func database(for url: URL) -> CompilationDatabase? {
128116
dispatchPrecondition(condition: .onQueue(queue))

Sources/SKCore/FallbackBuildSystem.swift

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -67,18 +67,6 @@ public final class FallbackBuildSystem: BuildSystem {
6767
/// We don't support change watching.
6868
public func unregisterForChangeNotifications(for: DocumentURI) {}
6969

70-
public func buildTargets(reply: @escaping (LSPResult<[BuildTarget]>) -> Void) {
71-
reply(.failure(buildTargetsNotSupported))
72-
}
73-
74-
public func buildTargetSources(targets: [BuildTargetIdentifier], reply: @escaping (LSPResult<[SourcesItem]>) -> Void) {
75-
reply(.failure(buildTargetsNotSupported))
76-
}
77-
78-
public func buildTargetOutputPaths(targets: [BuildTargetIdentifier], reply: @escaping (LSPResult<[OutputsItem]>) -> Void) {
79-
reply(.failure(buildTargetsNotSupported))
80-
}
81-
8270
func settingsSwift(_ file: String) -> FileBuildSettings {
8371
var args: [String] = []
8472
args.append(contentsOf: self.buildSetup.flags.swiftCompilerFlags)

Sources/SKSwiftPMWorkspace/SwiftPMWorkspace.swift

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -347,19 +347,6 @@ extension SwiftPMWorkspace: SKCore.BuildSystem {
347347
}
348348
}
349349

350-
public func buildTargets(reply: @escaping (LSPResult<[BuildTarget]>) -> Void) {
351-
// TODO: Support for build targets
352-
reply(.failure(buildTargetsNotSupported))
353-
}
354-
355-
public func buildTargetSources(targets: [BuildTargetIdentifier], reply: @escaping (LSPResult<[SourcesItem]>) -> Void) {
356-
reply(.failure(buildTargetsNotSupported))
357-
}
358-
359-
public func buildTargetOutputPaths(targets: [BuildTargetIdentifier], reply: @escaping (LSPResult<[OutputsItem]>) -> Void) {
360-
reply(.failure(buildTargetsNotSupported))
361-
}
362-
363350
/// Returns the resolved target description for the given file, if one is known.
364351
/// Must only be called on `queue`.
365352
private func targetDescription(for file: AbsolutePath) throws -> TargetBuildDescription? {

Tests/SKCoreTests/BuildServerBuildSystemTests.swift

Lines changed: 0 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -74,92 +74,6 @@ final class BuildServerBuildSystemTests: XCTestCase {
7474
XCTAssertEqual(XCTWaiter.wait(for: [expectation], timeout: defaultTimeout), .completed)
7575
}
7676

77-
func testBuildTargets() throws {
78-
let buildSystem = try BuildServerBuildSystem(projectRoot: root, buildFolder: buildFolder)
79-
80-
let expectation = XCTestExpectation(description: "build target expectation")
81-
82-
buildSystem.buildTargets(reply: { response in
83-
switch(response) {
84-
case .success(let targets):
85-
XCTAssertEqual(targets, [
86-
BuildTarget(id: BuildTargetIdentifier(uri: DocumentURI(string: "target:first_target")),
87-
displayName: "First Target",
88-
baseDirectory: DocumentURI(URL(fileURLWithPath: "/some/dir")),
89-
tags: [BuildTargetTag.library, BuildTargetTag.test],
90-
capabilities: BuildTargetCapabilities(canCompile: true, canTest: true, canRun: false),
91-
languageIds: [Language.objective_c, Language.swift],
92-
dependencies: []),
93-
BuildTarget(id: BuildTargetIdentifier(uri: DocumentURI(string: "target:second_target")),
94-
displayName: "Second Target",
95-
baseDirectory: DocumentURI(URL(fileURLWithPath: "/some/dir")),
96-
tags: [BuildTargetTag.library, BuildTargetTag.test],
97-
capabilities: BuildTargetCapabilities(canCompile: true, canTest: false, canRun: false),
98-
languageIds: [Language.objective_c, Language.swift],
99-
dependencies: [BuildTargetIdentifier(uri: DocumentURI(string: "target:first_target"))]),
100-
])
101-
expectation.fulfill()
102-
case .failure(let error):
103-
XCTFail(error.message)
104-
}
105-
})
106-
XCTAssertEqual(XCTWaiter.wait(for: [expectation], timeout: defaultTimeout), .completed)
107-
}
108-
109-
func testBuildTargetSources() throws {
110-
let buildSystem = try BuildServerBuildSystem(projectRoot: root, buildFolder: buildFolder)
111-
112-
let expectation = XCTestExpectation(description: "build target sources expectation")
113-
let targets = [
114-
BuildTargetIdentifier(uri: DocumentURI(string: "build://target/a")),
115-
BuildTargetIdentifier(uri: DocumentURI(string: "build://target/b")),
116-
]
117-
buildSystem.buildTargetSources(targets: targets, reply: { response in
118-
switch(response) {
119-
case .success(let items):
120-
XCTAssertNotNil(items)
121-
XCTAssertEqual(items[0].target.uri, targets[0].uri)
122-
XCTAssertEqual(items[1].target.uri, targets[1].uri)
123-
XCTAssertEqual(items[0].sources[0].uri, DocumentURI(URL(fileURLWithPath: "/path/to/a/file")))
124-
XCTAssertEqual(items[0].sources[0].kind, SourceItemKind.file)
125-
XCTAssertEqual(items[0].sources[1].uri, DocumentURI(URL(fileURLWithPath: "/path/to/a/folder", isDirectory: true)))
126-
XCTAssertEqual(items[0].sources[1].kind, SourceItemKind.directory)
127-
XCTAssertEqual(items[1].sources[0].uri, DocumentURI(URL(fileURLWithPath: "/path/to/b/file")))
128-
XCTAssertEqual(items[1].sources[0].kind, SourceItemKind.file)
129-
XCTAssertEqual(items[1].sources[1].uri, DocumentURI(URL(fileURLWithPath: "/path/to/b/folder", isDirectory: true)))
130-
XCTAssertEqual(items[1].sources[1].kind, SourceItemKind.directory)
131-
expectation.fulfill()
132-
case .failure(let error):
133-
XCTFail(error.message)
134-
}
135-
})
136-
XCTAssertEqual(XCTWaiter.wait(for: [expectation], timeout: defaultTimeout), .completed)
137-
}
138-
139-
func testBuildTargetOutputs() throws {
140-
let buildSystem = try BuildServerBuildSystem(projectRoot: root, buildFolder: buildFolder)
141-
142-
let expectation = XCTestExpectation(description: "build target output expectation")
143-
let targets = [
144-
BuildTargetIdentifier(uri: DocumentURI(string: "build://target/a")),
145-
]
146-
buildSystem.buildTargetOutputPaths(targets: targets, reply: { response in
147-
switch(response) {
148-
case .success(let items):
149-
XCTAssertNotNil(items)
150-
XCTAssertEqual(items[0].target.uri, targets[0].uri)
151-
XCTAssertEqual(items[0].outputPaths, [
152-
DocumentURI(URL(fileURLWithPath: "/path/to/a/file")),
153-
DocumentURI(URL(fileURLWithPath: "/path/to/a/file2")),
154-
])
155-
expectation.fulfill()
156-
case .failure(let error):
157-
XCTFail(error.message)
158-
}
159-
})
160-
XCTAssertEqual(XCTWaiter.wait(for: [expectation], timeout: defaultTimeout), .completed)
161-
}
162-
16377
func testBuildTargetsChanged() throws {
16478
let buildSystem = try BuildServerBuildSystem(projectRoot: root, buildFolder: buildFolder)
16579

Tests/SKCoreTests/BuildSystemManagerTests.swift

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -491,20 +491,6 @@ class ManualBuildSystem: BuildSystem {
491491
var indexDatabasePath: AbsolutePath? { nil }
492492
var indexPrefixMappings: [PathPrefixMapping] { return [] }
493493

494-
func buildTargets(reply: @escaping (LSPResult<[BuildTarget]>) -> Void) {
495-
fatalError()
496-
}
497-
498-
func buildTargetSources(targets: [BuildTargetIdentifier],
499-
reply: @escaping (LSPResult<[SourcesItem]>) -> Void) {
500-
fatalError()
501-
}
502-
503-
func buildTargetOutputPaths(targets: [BuildTargetIdentifier],
504-
reply: @escaping (LSPResult<[OutputsItem]>) -> Void) {
505-
fatalError()
506-
}
507-
508494
func filesDidChange(_ events: [FileEvent]) {}
509495

510496
public func fileHandlingCapability(for uri: DocumentURI) -> FileHandlingCapability {

0 commit comments

Comments
 (0)