Skip to content

Merge main into release/6.0 #1341

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 36 commits into from
May 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
ce34ec2
Fix issue that caused topological order to be incorrect
ahoppen May 21, 2024
41b810b
Cancel preparation tasks for editor functionality if the preparation …
ahoppen May 21, 2024
46f5b64
Merge pull request #1323 from ahoppen/dont-stack-preparation-for-editor
ahoppen May 22, 2024
44acd0d
Merge pull request #1325 from ahoppen/fix-topological-sorting
ahoppen May 22, 2024
a887981
Add an option to show the files that are currently being index / targ…
ahoppen May 22, 2024
3e6319c
Produce an index log for the client
ahoppen May 22, 2024
da96d45
Add a development subcommand to index a project
ahoppen May 22, 2024
2036729
Fix a non-deterministic test failure of `testTaskSuspension`
ahoppen May 22, 2024
6aecd22
Merge pull request #1330 from ahoppen/non-deterministic-task-schedule…
ahoppen May 22, 2024
30a16ec
Merge pull request #1326 from ahoppen/index-log
ahoppen May 22, 2024
814f3c5
Merge pull request #1329 from ahoppen/index-subcommand
ahoppen May 22, 2024
8263793
Add signposts for background preparation and indexing
ahoppen May 21, 2024
04d8c6b
Address review comments to #1322
ahoppen May 22, 2024
8f8ff45
Address review comments to #1326
ahoppen May 22, 2024
9757181
Fix a non-deterministic test failure in the task scheduler
ahoppen May 22, 2024
328a02a
Fix a race condition that caused `IndexProgressManager` to create two…
ahoppen May 22, 2024
60864fe
Respect failed work done progress creation
ahoppen May 22, 2024
406fb7e
Merge pull request #1331 from ahoppen/await-scheduling
ahoppen May 22, 2024
0615cb2
Merge pull request #1333 from ahoppen/index-progress-manager-creates-…
ahoppen May 22, 2024
927056b
Merge pull request #1327 from ahoppen/signposts
ahoppen May 22, 2024
950a74a
Fix a negation issue that prevented parallel indexing
ahoppen May 22, 2024
9e49f67
Rename `TestSourceKitLSPClient.handleNextRequest` to `handleSingleReq…
ahoppen May 22, 2024
3f7d9a7
Fix a non-deterministic test failure in `testPrepareTargetAfterEditTo…
ahoppen May 22, 2024
bc1cd2c
Merge pull request #1332 from ahoppen/review-comments-1322-1326
ahoppen May 22, 2024
69a584c
Merge pull request #1334 from ahoppen/respect-failed-work-done-progre…
ahoppen May 22, 2024
ed5655a
Merge pull request #1328 from ahoppen/parallel-indexing
ahoppen May 23, 2024
828be48
Disable `testTasksWithElevatedPrioritiesGetExecutedFirst`
hamishknight May 23, 2024
ed7a1d2
Merge pull request #1337 from hamishknight/disable-test
hamishknight May 23, 2024
9f0fce1
Fix a non-deterministic failure of `testBackgroundIndexingStatusWorkD…
ahoppen May 23, 2024
a671e5a
Merge pull request #1338 from ahoppen/fix-work-done-progress-test-fai…
ahoppen May 23, 2024
76da454
Re-generate sourcekitd UIDs
ahoppen May 23, 2024
c5e29b1
Don’t load the syntax map etc when re-opening a file
ahoppen May 10, 2024
00aebd6
Don’t cancel build when closing a document
ahoppen May 23, 2024
ba7b03c
Add a VSCode devcontainer definition (#916)
GeorgeLyon May 23, 2024
3300c77
Merge pull request #1339 from ahoppen/dont-cancel-sourcekitd-request-…
ahoppen May 24, 2024
9e771aa
Merge branch 'main' into 6.0/merge-main-2024-05-23
ahoppen May 24, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions .devcontainer/Readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
## Using VSCode devcontainers

Official tutorial: https://code.visualstudio.com/docs/devcontainers/tutorial

### Recommended Settings for macOS

Some of these are defaults:
- Recommended settings for macOS (some of these are defaults):
- General:
- "Choose file sharing implementation for your containers": VirtioFS (better IO performance)
- Resources:
- CPUs: Allow docker to use most or all of your CPUs
- Memory: Allow docker to use most or all of your memory
10 changes: 10 additions & 0 deletions .devcontainer/default/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
FROM swiftlang/swift:nightly-main-jammy

RUN \
# Disable apt interactive prompts for this RUN command
export DEBIAN_FRONTEND="noninteractive" && \
# Update apt package list
apt-get update && \
# Install sourcekit-lsp dependencies
apt-get install -y libsqlite3-dev libncurses5-dev python3

32 changes: 32 additions & 0 deletions .devcontainer/default/devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Reference: https://containers.dev/implementors/json_reference/
{
"name": "SourceKit-LSP",
"dockerFile": "Dockerfile",

// Allow the processes in the container to attach a debugger
"capAdd": [ "SYS_PTRACE" ],
"securityOpt": [ "seccomp=unconfined" ],

"mounts": [
// Use a named volume for the build products for optimal performance (https://code.visualstudio.com/remote/advancedcontainers/improve-performance#_use-a-targeted-named-volume)
"source=${localWorkspaceFolderBasename}-build,target=${containerWorkspaceFolder}/.build,type=volume",
// Do the same for experimental background indexing
"source=${localWorkspaceFolderBasename}-index-build,target=${containerWorkspaceFolder}/.index-build,type=volume"
],
"customizations": {
"vscode": {
"extensions": [
"sswg.swift-lang"
],
"settings": {
"lldb.library": "/usr/lib/liblldb.so",
"swift.buildArguments": [
"-Xcxx",
"-I/usr/lib/swift",
"-Xcxx",
"-I/usr/lib/swift/Block"
]
}
}
}
}
3 changes: 1 addition & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@
default.profraw
Package.resolved
/.build
/.index-build
/.linux-build
/.*-build
/Packages
/*.xcodeproj
/*.sublime-project
Expand Down
21 changes: 20 additions & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,12 @@ let package = Package(
.target(
name: "Diagnose",
dependencies: [
"InProcessClient",
"LSPLogging",
"SourceKitD",
"SKCore",
"SKSupport",
"SourceKitD",
"SourceKitLSP",
.product(name: "ArgumentParser", package: "swift-argument-parser"),
.product(name: "SwiftIDEUtils", package: "swift-syntax"),
.product(name: "SwiftSyntax", package: "swift-syntax"),
Expand All @@ -99,6 +102,20 @@ let package = Package(
]
),

// MARK: InProcessClient

.target(
name: "InProcessClient",
dependencies: [
"CAtomics",
"LanguageServerProtocol",
"LSPLogging",
"SKCore",
"SourceKitLSP",
],
exclude: ["CMakeLists.txt"]
),

// MARK: LanguageServerProtocol
// The core LSP types, suitable for any LSP implementation.
.target(
Expand Down Expand Up @@ -162,6 +179,7 @@ let package = Package(
.target(
name: "LSPTestSupport",
dependencies: [
"InProcessClient",
"LanguageServerProtocol",
"LanguageServerProtocolJSONRPC",
"SKSupport",
Expand Down Expand Up @@ -278,6 +296,7 @@ let package = Package(
name: "SKTestSupport",
dependencies: [
"CSKTestSupport",
"InProcessClient",
"LanguageServerProtocol",
"LSPTestSupport",
"LSPLogging",
Expand Down
1 change: 1 addition & 0 deletions Sources/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ add_subdirectory(BuildServerProtocol)
add_subdirectory(CAtomics)
add_subdirectory(Csourcekitd)
add_subdirectory(Diagnose)
add_subdirectory(InProcessClient)
add_subdirectory(LanguageServerProtocol)
add_subdirectory(LanguageServerProtocolJSONRPC)
add_subdirectory(LSPLogging)
Expand Down
3 changes: 3 additions & 0 deletions Sources/Diagnose/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ add_library(Diagnose STATIC
CommandConfiguration+Sendable.swift
CommandLineArgumentsReducer.swift
DiagnoseCommand.swift
IndexCommand.swift
MergeSwiftFiles.swift
OSLogScraper.swift
ReduceCommand.swift
Expand All @@ -23,6 +24,8 @@ set_target_properties(Diagnose PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_Swift_MODULE_DIRECTORY})

target_link_libraries(Diagnose PUBLIC
InProcessClient
LSPLogging
SKCore
SourceKitD
ArgumentParser
Expand Down
111 changes: 111 additions & 0 deletions Sources/Diagnose/IndexCommand.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2024 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

import ArgumentParser
import Foundation
import InProcessClient
import LanguageServerProtocol
import SKCore
import SKSupport
import SourceKitLSP

import struct TSCBasic.AbsolutePath
import class TSCBasic.Process
import var TSCBasic.stderrStream
import class TSCUtility.PercentProgressAnimation

private actor IndexLogMessageHandler: MessageHandler {
var hasSeenError: Bool = false

/// Queue to ensure that we don't have two interleaving `print` calls.
let queue = AsyncQueue<Serial>()

nonisolated func handle(_ notification: some NotificationType) {
if let notification = notification as? LogMessageNotification {
queue.async {
await self.handle(notification)
}
}
}

func handle(_ notification: LogMessageNotification) {
self.hasSeenError = notification.type == .warning
print(notification.message)
}

nonisolated func handle<Request: RequestType>(
_ request: Request,
id: RequestID,
reply: @escaping @Sendable (LSPResult<Request.Response>) -> Void
) {
reply(.failure(.methodNotFound(Request.method)))
}

}

public struct IndexCommand: AsyncParsableCommand {
public static let configuration: CommandConfiguration = CommandConfiguration(
commandName: "index",
abstract: "Index a project and print all the processes executed for it as well as their outputs",
shouldDisplay: false
)

@Option(
name: .customLong("toolchain"),
help: """
The toolchain used to reduce the sourcekitd issue. \
If not specified, the toolchain is found in the same way that sourcekit-lsp finds it
"""
)
var toolchainOverride: String?

@Option(help: "The path to the project that should be indexed")
var project: String

public init() {}

public func run() async throws {
var serverOptions = SourceKitLSPServer.Options()
serverOptions.indexOptions.enableBackgroundIndexing = true

let installPath =
if let toolchainOverride, let toolchain = Toolchain(try AbsolutePath(validating: toolchainOverride)) {
toolchain.path
} else {
try AbsolutePath(validating: Bundle.main.bundlePath)
}

let messageHandler = IndexLogMessageHandler()
let inProcessClient = try await InProcessSourceKitLSPClient(
toolchainRegistry: ToolchainRegistry(installPath: installPath),
serverOptions: serverOptions,
workspaceFolders: [WorkspaceFolder(uri: DocumentURI(URL(fileURLWithPath: project)))],
messageHandler: messageHandler
)
let start = ContinuousClock.now
_ = try await inProcessClient.send(PollIndexRequest())
print("Indexing finished in \(start.duration(to: .now))")
if await messageHandler.hasSeenError {
throw ExitCode(1)
}
}
}

fileprivate extension SourceKitLSPServer {
func handle<R: RequestType>(_ request: R, requestID: RequestID) async throws -> R.Response {
return try await withCheckedThrowingContinuation { continuation in
self.handle(request, id: requestID) { result in
continuation.resume(with: result)
}
}
}
}
14 changes: 14 additions & 0 deletions Sources/InProcessClient/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
add_library(InProcessClient STATIC
InProcessSourceKitLSPClient.swift
LocalConnection.swift)

set_target_properties(InProcessClient PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_Swift_MODULE_DIRECTORY})

target_link_libraries(InProcessClient PUBLIC
CAtomics
LanguageServerProtocol
LSPLogging
SKCore
SourceKitLSP
)
81 changes: 81 additions & 0 deletions Sources/InProcessClient/InProcessSourceKitLSPClient.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2024 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

import CAtomics
import LanguageServerProtocol
import SKCore
import SourceKitLSP

/// Launches a `SourceKitLSPServer` in-process and allows sending messages to it.
public final class InProcessSourceKitLSPClient: Sendable {
private let server: SourceKitLSPServer

/// `nonisolated(unsafe)` if fine because `nextRequestID` is atomic.
private nonisolated(unsafe) var nextRequestID = AtomicUInt32(initialValue: 0)

/// Create a new `SourceKitLSPServer`. An `InitializeRequest` is automatically sent to the server.
///
/// `messageHandler` handles notifications and requests sent from the SourceKit-LSP server to the client.
public init(
toolchainRegistry: ToolchainRegistry,
serverOptions: SourceKitLSPServer.Options = SourceKitLSPServer.Options(),
capabilities: ClientCapabilities = ClientCapabilities(),
workspaceFolders: [WorkspaceFolder],
messageHandler: any MessageHandler
) async throws {
let serverToClientConnection = LocalConnection(name: "client")
self.server = SourceKitLSPServer(
client: serverToClientConnection,
toolchainRegistry: toolchainRegistry,
options: serverOptions,
onExit: {
serverToClientConnection.close()
}
)
serverToClientConnection.start(handler: messageHandler)
_ = try await self.send(
InitializeRequest(
processId: nil,
rootPath: nil,
rootURI: nil,
initializationOptions: nil,
capabilities: capabilities,
trace: .off,
workspaceFolders: workspaceFolders
)
)
}

/// Send the request to `server` and return the request result.
///
/// - Important: Because this is an async function, Swift concurrency makes no guarantees about the execution ordering
/// of this request with regard to other requests to the server. If execution of requests in a particular order is
/// necessary and the response of the request is not awaited, use the version of the function that takes a
/// completion handler
public func send<R: RequestType>(_ request: R) async throws -> R.Response {
return try await withCheckedThrowingContinuation { continuation in
self.send(request) {
continuation.resume(with: $0)
}
}
}

/// Send the request to `server` and return the request result via a completion handler.
public func send<R: RequestType>(_ request: R, reply: @Sendable @escaping (LSPResult<R.Response>) -> Void) {
server.handle(request, id: .number(Int(nextRequestID.fetchAndIncrement())), reply: reply)
}

/// Send the notification to `server`.
public func send(_ notification: some NotificationType) {
server.handle(notification)
}
}
3 changes: 2 additions & 1 deletion Sources/LSPLogging/NonDarwinLogging.swift
Original file line number Diff line number Diff line change
Expand Up @@ -394,5 +394,6 @@ public struct NonDarwinSignposter: Sendable {

public func emitEvent(_ name: StaticString, id: NonDarwinSignpostID, _ message: NonDarwinLogMessage = "") {}

public func endInterval(_ name: StaticString, _ state: NonDarwinSignpostIntervalState, _ message: StaticString) {}
public func endInterval(_ name: StaticString, _ state: NonDarwinSignpostIntervalState, _ message: StaticString = "") {
}
}
1 change: 1 addition & 0 deletions Sources/LSPTestSupport/TestJSONRPCConnection.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
//
//===----------------------------------------------------------------------===//

import InProcessClient
import LanguageServerProtocol
import LanguageServerProtocolJSONRPC
import SKSupport
Expand Down
5 changes: 4 additions & 1 deletion Sources/SKCore/BuildServerBuildSystem.swift
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,10 @@ extension BuildServerBuildSystem: BuildSystem {
return nil
}

public func prepare(targets: [ConfiguredTarget]) async throws {
public func prepare(
targets: [ConfiguredTarget],
indexProcessDidProduceResult: @Sendable (IndexProcessResult) -> Void
) async throws {
throw PrepareNotSupportedError()
}

Expand Down
5 changes: 4 additions & 1 deletion Sources/SKCore/BuildSystem.swift
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,10 @@ public protocol BuildSystem: AnyObject, Sendable {

/// Prepare the given targets for indexing and semantic functionality. This should build all swift modules of target
/// dependencies.
func prepare(targets: [ConfiguredTarget]) async throws
func prepare(
targets: [ConfiguredTarget],
indexProcessDidProduceResult: @Sendable (IndexProcessResult) -> Void
) async throws

/// If the build system has knowledge about the language that this document should be compiled in, return it.
///
Expand Down
Loading