Skip to content

Merge main -> release/6.2 #2130

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 54 commits into from
May 2, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
bf1c0fa
Generalize educational notes documentation test to not require the ".…
DougGregor Apr 15, 2025
2c1b859
Merge pull request #2112 from DougGregor/educational-notes-diags-gene…
DougGregor Apr 15, 2025
b0991df
Improve educational-notes test
DougGregor Apr 16, 2025
12dc048
Merge pull request #2113 from DougGregor/improve-educational-notes-test
DougGregor Apr 16, 2025
39bf485
handle Markdown and Tutorial files in textDocument/doccDocumentation
matthewbastien Nov 22, 2024
24118eb
cleanup unused code
matthewbastien Mar 19, 2025
49b3f53
move SwiftDocC related functionality into its own module
matthewbastien Mar 19, 2025
c1a6e65
add CMake build to DocCDocumentation module
matthewbastien Mar 19, 2025
a8eae3c
remove protocols from DocCDocumentation module
matthewbastien Mar 25, 2025
0adaf25
more robust searching for DocC catalogs
matthewbastien Mar 25, 2025
1ca1441
fix some review comments
matthewbastien Mar 25, 2025
3709e40
adjust position markers in tests
matthewbastien Mar 26, 2025
f6f1cb3
remove public access modifiers from package symbols
matthewbastien Mar 26, 2025
909e639
add missing copyright header
matthewbastien Mar 26, 2025
8c15e27
use a helper document in cursorInfo()
matthewbastien Mar 27, 2025
4e06c36
organize imports
matthewbastien Mar 28, 2025
0ea0e00
use LinkCompletionTools to parse SwiftDocC symbol links
matthewbastien Apr 1, 2025
0e05bca
remove isHeader from SourceKitSourceItemData
matthewbastien Apr 16, 2025
c1895c3
add logging to BuildSystemIntegrationExtensions
matthewbastien Apr 16, 2025
b9e93f7
add logging of failure cases to DocCCatalogIndexManager
matthewbastien Apr 16, 2025
f77e323
update invalidation logic for DocC catalogs
matthewbastien Apr 16, 2025
1de68c5
add logging to DocCReferenceResolutionService
matthewbastien Apr 16, 2025
0151774
simplify logic for DocCSymbolInformation.matches(_:)
matthewbastien Apr 16, 2025
9cdd1ac
simplify logic for CheckedIndex.primaryDefinitionOrDeclarationOccurre…
matthewbastien Apr 16, 2025
1c65bda
remove some nesting levels in DocumentationLanguageService.doccDocume…
matthewbastien Apr 16, 2025
131c811
add logging to SwiftLanguageService.doccDocumentation(_:)
matthewbastien Apr 16, 2025
c37c596
fix newline matching
matthewbastien Apr 16, 2025
c24f92d
add documentation for certain functions
matthewbastien Apr 16, 2025
2ae2e70
add LRUCache struct to SKUtilities
matthewbastien Apr 17, 2025
3610593
remove closeDocument(uri:) from TestSourceKitLSPClient
matthewbastien Apr 17, 2025
c401306
Overview.md: Correct path to sourcekit-lsp logs
Wilfred Apr 18, 2025
875199b
update launch configuration for Swift extension v2.2.0
matthewbastien Apr 22, 2025
4fb5323
add cursorInfoFromDisk() to SwiftLanguageService
matthewbastien Apr 22, 2025
9743e77
Merge pull request #2116 from Wilfred/patch-1
ahoppen Apr 23, 2025
bbbc93e
Refactor `cursorInfoFromDisk` to share the underlying logic of invoki…
ahoppen Apr 23, 2025
024efc2
Remove dependency from `SourceKitLSP` on `swift-docc-symbolkit`
ahoppen Apr 23, 2025
1355b20
Use on-disk contents of a source file to get the position of a symbol…
ahoppen Apr 23, 2025
bc4d9c7
Remove `public` modifiers from `MarkdownTitleFinder`
ahoppen Apr 23, 2025
d8aeeaf
Only pass key and not value to `LRUCache.removeAll(where:)`
ahoppen Apr 23, 2025
d3c2d04
Use `<` for canonical sorting of catalog URLs
ahoppen Apr 23, 2025
82c5fa9
Remove `snapshotFromDisk`
ahoppen Apr 23, 2025
f433f58
Miscellaneous small cleanups
ahoppen Apr 23, 2025
30ac972
Remove `FileBuildSettings.patching` that takes a `String`
ahoppen Apr 23, 2025
11d5bec
Add missing dependency declarations to Package.swift
ahoppen Apr 24, 2025
ae7f80f
Merge pull request #2121 from ahoppen/missing-dependencies
ahoppen Apr 24, 2025
17daedd
add LRUCache to CMakeLists
matthewbastien Apr 25, 2025
ab64878
Merge pull request #2120 from matthewbastien/launch-config
matthewbastien Apr 25, 2025
242609d
Merge pull request #1959 from matthewbastien/markdown-documentation
ahoppen Apr 26, 2025
227ab8f
Correct logging docs
MahdiBM Apr 28, 2025
efe6c7f
Fix experimental feature command line flag + other improvements
MahdiBM Apr 28, 2025
b921e94
NFC: Create `.editorconfig` (#2125)
MaxDesiatov Apr 28, 2025
d97b005
Merge pull request #2123 from MahdiBM/patch-2
ahoppen Apr 29, 2025
71c205d
Merge pull request #2124 from MahdiBM/fix-experimenta-features-flag
ahoppen Apr 29, 2025
682124a
Merge remote-tracking branch 'origin/main' into release/6.2
bnbarham Apr 29, 2025
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
10 changes: 10 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
root = true

[*]
charset = utf-8
end_of_line = lf
indent_style = space
indent_size = 2
trim_trailing_whitespace = true
insert_final_newline = true
xcode_trim_whitespace_on_empty_lines = true
9 changes: 3 additions & 6 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -1,31 +1,28 @@
{
"configurations": [
{
"type": "lldb",
"type": "swift",
"request": "launch",
"name": "Debug sourcekit-lsp",
"program": "${workspaceFolder:sourcekit-lsp}/.build/debug/sourcekit-lsp",
"args": [],
"cwd": "${workspaceFolder:sourcekit-lsp}",
"preLaunchTask": "swift: Build Debug sourcekit-lsp",
"sourceLanguages": ["swift"]
},
{
"type": "lldb",
"type": "swift",
"request": "launch",
"name": "Release sourcekit-lsp",
"program": "${workspaceFolder:sourcekit-lsp}/.build/release/sourcekit-lsp",
"args": [],
"cwd": "${workspaceFolder:sourcekit-lsp}",
"preLaunchTask": "swift: Build Release sourcekit-lsp",
"sourceLanguages": ["swift"]
},
{
"type": "lldb",
"type": "swift",
"request": "attach",
"name": "Attach sourcekit-lsp (debug)",
"program": "${workspaceFolder:sourcekit-lsp}/.build/debug/sourcekit-lsp",
"sourceLanguages": ["swift"],
"waitFor": true
}
]
Expand Down
6 changes: 5 additions & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ To adjust the toolchain that should be used by SourceKit-LSP (eg. because you wa

## Logging

SourceKit-LSP has extensive logging to the system log on macOS and to `/var/logs/sourcekit-lsp` or stderr on other platforms.
SourceKit-LSP has extensive logging to the system log on macOS and to `~/.sourcekit-lsp/logs/` or stderr on other platforms.

To show the logs on macOS, run
```sh
Expand All @@ -100,6 +100,10 @@ Or to stream the logs as they are produced:
```
log stream --predicate 'subsystem CONTAINS "org.swift.sourcekit-lsp"' --level debug
```
On non-Apple platforms, you can use common commands like `tail` to read the logs or stream them as they are produced:
```
tail -F ~/.sourcekit-lsp/logs/*
```

SourceKit-LSP masks data that may contain private information such as source file names and contents by default. To enable logging of this information, follow the instructions in [Diagnose Bundle.md](Documentation/Diagnose%20Bundle.md).

Expand Down
17 changes: 6 additions & 11 deletions Contributor Documentation/BSP Extensions.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,18 +76,13 @@ export interface PrepareParams {
```ts
export interface SourceKitSourceItemData {
/** The language of the source file. If `nil`, the language is inferred from the file extension. */
language? LanguageId;
language?: LanguageId;

/** Whether the file is a header file that is clearly associated with one target.
*
* For example header files in SwiftPM projects are always associated to one target and SwiftPM can provide build
* settings for that header file.
*
* In general, build systems don't need to list all header files in the `buildTarget/sources` request: Semantic
* functionality for header files is usually provided by finding a main file that includes the header file and
* inferring build settings from it. Listing header files in `buildTarget/sources` allows SourceKit-LSP to provide
* semantic functionality for header files if they haven't been included by any main file. **/
isHeader?: bool;
/**
* The kind of source file that this source item represents. If omitted, the item is assumed to be a normal source
* file, ie. omitting this key is equivalent to specifying it as `source`.
*/
kind?: "source" | "header" | "doccCatalog";

/**
* The output path that is during indexing for this file, ie. the `-index-unit-output-path`, if it is specified
Expand Down
2 changes: 1 addition & 1 deletion Contributor Documentation/Overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,4 @@ SourceKit-LSP has fairly extensive logging to help diagnose issues. The way logg

On macOS, SourceKit-LSP logs to the system log. [CONTRIBUTING.md](../CONTRIBUTING.md#logging) contains some information about how to read the system logs. Since [OSLog](https://developer.apple.com/documentation/os/logging) cannot be wrapped, the decision to log to macOS’s system log is done at build time and cannot be modified at runtime.

On other platforms, the `NonDarwinLogger` types are used to log messages. These types are API-compatible with OSLog. Log messages are written to stderr by default. When possible, `SourceKitLSP.run` will redirect the log messages to log files in `/var/log/sourcekit-lsp` on launch.
On other platforms, the `NonDarwinLogger` types are used to log messages. These types are API-compatible with OSLog. Log messages are written to stderr by default. When possible, `SourceKitLSP.run` will redirect the log messages to log files in `~/.sourcekit-lsp` on launch.
28 changes: 27 additions & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,25 @@ var targets: [Target] = [
swiftSettings: globalSwiftSettings
),

// MARK: DocCDocumentation

.target(
name: "DocCDocumentation",
dependencies: [
"BuildServerProtocol",
"BuildSystemIntegration",
"LanguageServerProtocol",
"SemanticIndex",
"SKLogging",
"SwiftExtensions",
.product(name: "IndexStoreDB", package: "indexstore-db"),
.product(name: "SwiftDocC", package: "swift-docc"),
.product(name: "SymbolKit", package: "swift-docc-symbolkit"),
],
exclude: ["CMakeLists.txt"],
swiftSettings: globalSwiftSettings
),

// MARK: InProcessClient

.target(
Expand Down Expand Up @@ -292,8 +311,10 @@ var targets: [Target] = [
.target(
name: "SemanticIndex",
dependencies: [
"BuildServerProtocol",
"BuildSystemIntegration",
"LanguageServerProtocol",
"LanguageServerProtocolExtensions",
"SKLogging",
"SwiftExtensions",
"ToolchainRegistry",
Expand Down Expand Up @@ -474,6 +495,7 @@ var targets: [Target] = [
dependencies: [
"BuildServerProtocol",
"BuildSystemIntegration",
"DocCDocumentation",
"LanguageServerProtocol",
"LanguageServerProtocolExtensions",
"LanguageServerProtocolJSONRPC",
Expand All @@ -485,9 +507,9 @@ var targets: [Target] = [
"SwiftExtensions",
"ToolchainRegistry",
"TSCExtensions",
.product(name: "SwiftDocC", package: "swift-docc"),
.product(name: "IndexStoreDB", package: "indexstore-db"),
.product(name: "Crypto", package: "swift-crypto"),
.product(name: "Markdown", package: "swift-markdown"),
.product(name: "SwiftToolsSupport-auto", package: "swift-tools-support-core"),
]
+ swiftPMDependency([
Expand Down Expand Up @@ -770,6 +792,8 @@ var dependencies: [Package.Dependency] {
return [
.package(path: "../indexstore-db"),
.package(path: "../swift-docc"),
.package(path: "../swift-docc-symbolkit"),
.package(path: "../swift-markdown"),
.package(path: "../swift-tools-support-core"),
.package(path: "../swift-argument-parser"),
.package(path: "../swift-syntax"),
Expand All @@ -781,6 +805,8 @@ var dependencies: [Package.Dependency] {
return [
.package(url: "https://github.com/swiftlang/indexstore-db.git", branch: relatedDependenciesBranch),
.package(url: "https://github.com/swiftlang/swift-docc.git", branch: relatedDependenciesBranch),
.package(url: "https://github.com/swiftlang/swift-docc-symbolkit.git", branch: relatedDependenciesBranch),
.package(url: "https://github.com/swiftlang/swift-markdown.git", branch: relatedDependenciesBranch),
.package(url: "https://github.com/apple/swift-tools-support-core.git", branch: relatedDependenciesBranch),
.package(url: "https://github.com/apple/swift-argument-parser.git", from: "1.4.0"),
.package(url: "https://github.com/swiftlang/swift-syntax.git", branch: relatedDependenciesBranch),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,11 +119,12 @@ public struct SourceItemDataKind: RawRepresentable, Codable, Hashable, Sendable
}

/// **(BSP Extension)**
public struct SourceKitSourceItemData: LSPAnyCodable, Codable {
/// The language of the source file. If `nil`, the language is inferred from the file extension.
public var language: Language?

/// Whether the file is a header file that is clearly associated with one target.
public enum SourceKitSourceItemKind: String, Codable {
/// A source file that belongs to the target
case source = "source"

/// A header file that is clearly associated with one target.
///
/// For example header files in SwiftPM projects are always associated to one target and SwiftPM can provide build
/// settings for that header file.
Expand All @@ -132,7 +133,19 @@ public struct SourceKitSourceItemData: LSPAnyCodable, Codable {
/// functionality for header files is usually provided by finding a main file that includes the header file and
/// inferring build settings from it. Listing header files in `buildTarget/sources` allows SourceKit-LSP to provide
/// semantic functionality for header files if they haven't been included by any main file.
public var isHeader: Bool?
case header = "header"

/// A SwiftDocC documentation catalog usually ending in the ".docc" extension.
case doccCatalog = "doccCatalog"
}

public struct SourceKitSourceItemData: LSPAnyCodable, Codable {
/// The language of the source file. If `nil`, the language is inferred from the file extension.
public var language: Language?

/// The kind of source file that this source item represents. If omitted, the item is assumed to be a normal source file,
/// ie. omitting this key is equivalent to specifying it as `source`.
public var kind: SourceKitSourceItemKind?

/// The output path that is used during indexing for this file, ie. the `-index-unit-output-path`, if it is specified
/// in the compiler arguments or the file that is passed as `-o`, if `-index-unit-output-path` is not specified.
Expand All @@ -144,18 +157,22 @@ public struct SourceKitSourceItemData: LSPAnyCodable, Codable {
/// `outputPathsProvider: true` in `SourceKitInitializeBuildResponseData`.
public var outputPath: String?

public init(language: Language? = nil, isHeader: Bool? = nil, outputPath: String? = nil) {
public init(language: Language? = nil, kind: SourceKitSourceItemKind? = nil, outputPath: String? = nil) {
self.language = language
self.isHeader = isHeader
self.kind = kind
self.outputPath = outputPath
}

public init?(fromLSPDictionary dictionary: [String: LanguageServerProtocol.LSPAny]) {
if case .string(let language) = dictionary[CodingKeys.language.stringValue] {
self.language = Language(rawValue: language)
}
if case .bool(let isHeader) = dictionary[CodingKeys.isHeader.stringValue] {
self.isHeader = isHeader
if case .string(let rawKind) = dictionary[CodingKeys.kind.stringValue] {
self.kind = SourceKitSourceItemKind(rawValue: rawKind)
}
// Backwards compatibility for isHeader
if case .bool(let isHeader) = dictionary["isHeader"], isHeader {
self.kind = .header
}
if case .string(let outputFilePath) = dictionary[CodingKeys.outputPath.stringValue] {
self.outputPath = outputFilePath
Expand All @@ -167,8 +184,8 @@ public struct SourceKitSourceItemData: LSPAnyCodable, Codable {
if let language {
result[CodingKeys.language.stringValue] = .string(language.rawValue)
}
if let isHeader {
result[CodingKeys.isHeader.stringValue] = .bool(isHeader)
if let kind {
result[CodingKeys.kind.stringValue] = .string(kind.rawValue)
}
if let outputPath {
result[CodingKeys.outputPath.stringValue] = .string(outputPath)
Expand Down
2 changes: 1 addition & 1 deletion Sources/BuildSystemIntegration/BuildSystemManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1266,7 +1266,7 @@ package actor BuildSystemManager: QueueBasedMessageHandler {
isPartOfRootProject: isPartOfRootProject,
mayContainTests: mayContainTests,
isBuildable: !(target?.tags.contains(.notBuildable) ?? false)
&& !(sourceKitData?.isHeader ?? false)
&& (sourceKitData?.kind ?? .source) == .source
)
switch sourceItem.kind {
case .file:
Expand Down
2 changes: 1 addition & 1 deletion Sources/BuildSystemIntegration/FileBuildSettings.swift
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ package struct FileBuildSettings: Equatable, Sendable {
///
/// This patches the arguments by searching for the argument corresponding to
/// `originalFile` and replacing it.
func patching(newFile: DocumentURI, originalFile: DocumentURI) -> FileBuildSettings {
package func patching(newFile: DocumentURI, originalFile: DocumentURI) -> FileBuildSettings {
var arguments = self.compilerArguments
// URL.lastPathComponent is only set for file URLs but we want to also infer a file extension for non-file URLs like
// untitled:file.cpp
Expand Down
23 changes: 15 additions & 8 deletions Sources/BuildSystemIntegration/SwiftPMBuildSystem.swift
Original file line number Diff line number Diff line change
Expand Up @@ -593,16 +593,23 @@ package actor SwiftPMBuildSystem: BuiltInBuildSystem {
kind: .file,
generated: false,
dataKind: .sourceKit,
data: SourceKitSourceItemData(isHeader: true).encodeToLSPAny()
)
}
sources += (swiftPMTarget.resources + swiftPMTarget.ignored + swiftPMTarget.others).map {
SourceItem(
uri: DocumentURI($0),
kind: $0.isDirectory ? .directory : .file,
generated: false
data: SourceKitSourceItemData(kind: .header).encodeToLSPAny()
)
}
sources += (swiftPMTarget.resources + swiftPMTarget.ignored + swiftPMTarget.others)
.map { (url: URL) -> SourceItem in
var data: SourceKitSourceItemData? = nil
if url.isDirectory, url.pathExtension == "docc" {
data = SourceKitSourceItemData(kind: .doccCatalog)
}
return SourceItem(
uri: DocumentURI(url),
kind: url.isDirectory ? .directory : .file,
generated: false,
dataKind: data != nil ? .sourceKit : nil,
data: data?.encodeToLSPAny()
)
}
result.append(SourcesItem(target: target, sources: sources))
}
return BuildTargetSourcesResponse(items: result)
Expand Down
4 changes: 2 additions & 2 deletions Sources/Diagnose/IndexCommand.swift
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,10 @@ package struct IndexCommand: AsyncParsableCommand {
var toolchainOverride: String?

@Option(
name: .customLong("experimental-index-feature"),
name: .customLong("experimental-feature"),
help: """
Enable an experimental sourcekit-lsp feature.
Available features are: \(ExperimentalFeature.allCases.map(\.rawValue).joined(separator: ", "))
Available features are: \(ExperimentalFeature.allNonInternalCases.map(\.rawValue).joined(separator: ", "))
"""
)
var experimentalFeatures: [ExperimentalFeature] = []
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2025 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
//
//===----------------------------------------------------------------------===//

package import BuildServerProtocol
package import BuildSystemIntegration
package import Foundation
import LanguageServerProtocol
import SKLogging

package extension BuildSystemManager {
/// Retrieves the name of the Swift module for a given target.
///
/// **Note:** prefer using ``module(for:in:)`` over ths function. This function
/// only exists for cases where you want the Swift module name of a target where
/// you don't know one of its Swift document URIs in advance. E.g. when handling
/// requests for Markdown/Tutorial files in DocC since they don't have compile
/// commands that could be used to find the module name.
///
/// - Parameter target: The build target identifier
/// - Returns: The name of the Swift module or nil if it could not be determined
func moduleName(for target: BuildTargetIdentifier) async -> String? {
let sourceFiles =
await orLog(
"Failed to retreive source files from target \(target.uri)",
{ try await self.sourceFiles(in: [target]).flatMap(\.sources) }
) ?? []
for sourceFile in sourceFiles {
let language = await defaultLanguage(for: sourceFile.uri, in: target)
guard language == .swift else {
continue
}
if let moduleName = await moduleName(for: sourceFile.uri, in: target) {
return moduleName
}
}
return nil
}

/// Finds the SwiftDocC documentation catalog associated with a target, if any.
///
/// - Parameter target: The build target identifier
/// - Returns: The URL of the documentation catalog or nil if one could not be found
func doccCatalog(for target: BuildTargetIdentifier) async -> URL? {
let sourceFiles =
await orLog(
"Failed to retrieve source files from target \(target.uri)",
{ try await self.sourceFiles(in: [target]).flatMap(\.sources) }
) ?? []
let catalogURLs = sourceFiles.compactMap { sourceItem -> URL? in
guard sourceItem.dataKind == .sourceKit,
let data = SourceKitSourceItemData(fromLSPAny: sourceItem.data),
data.kind == .doccCatalog
else {
return nil
}
return sourceItem.uri.fileURL
}.sorted(by: { $0.absoluteString < $1.absoluteString })
if catalogURLs.count > 1 {
logger.error("Multiple SwiftDocC catalogs found in build target \(target.uri)")
}
return catalogURLs.first
}
}
Loading