Skip to content

Commit 69121ee

Browse files
authored
Merge pull request #1906 from ahoppen/add-sourcekit-plugin
Add a SourceKit plugin to handle code completion requests
2 parents f60752b + 43a81ae commit 69121ee

File tree

144 files changed

+21928
-108
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

144 files changed

+21928
-108
lines changed

Documentation/Environment Variables.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,4 @@ The following environment variables can be used to control some behavior in Sour
1818
- `SOURCEKIT_LSP_KEEP_TEST_SCRATCH_DIR`: Does not delete the temporary files created during test execution. Allows inspection of the test projects after the test finishes.
1919
- `SOURCEKIT_LSP_TEST_MODULE_CACHE`: Specifies where tests should store their shared module cache. Defaults to writing the module cache to a temporary directory. Intended so that CI systems can clean the module cache directory after running.
2020
- `SOURCEKIT_LSP_TEST_TIMEOUT`: Override the timeout duration for tests, in seconds.
21+
- `SOURCEKIT_LSP_TEST_PLUGIN_PATHS`: Load the SourceKit plugins from this path instead of relative to the package's build folder.

Package.swift

Lines changed: 174 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ var products: [Product] = [
1313
.executable(name: "sourcekit-lsp", targets: ["sourcekit-lsp"]),
1414
.library(name: "_SourceKitLSP", targets: ["SourceKitLSP"]),
1515
.library(name: "LSPBindings", targets: ["LanguageServerProtocol", "LanguageServerProtocolJSONRPC"]),
16+
.library(name: "SwiftSourceKitPlugin", type: .dynamic, targets: ["SwiftSourceKitPlugin"]),
17+
.library(name: "SwiftSourceKitClientPlugin", type: .dynamic, targets: ["SwiftSourceKitClientPlugin"]),
1618
]
1719

1820
var targets: [Target] = [
@@ -111,6 +113,45 @@ var targets: [Target] = [
111113
dependencies: []
112114
),
113115

116+
.target(
117+
name: "CCompletionScoring",
118+
dependencies: []
119+
),
120+
121+
// MARK: CompletionScoring
122+
123+
.target(
124+
name: "CompletionScoring",
125+
dependencies: ["CCompletionScoring"],
126+
swiftSettings: globalSwiftSettings
127+
),
128+
129+
.target(
130+
name: "CompletionScoringForPlugin",
131+
dependencies: ["CCompletionScoring"],
132+
swiftSettings: globalSwiftSettings
133+
),
134+
135+
.testTarget(
136+
name: "CompletionScoringTests",
137+
dependencies: ["CompletionScoring", "CompletionScoringTestSupport", "SwiftExtensions"],
138+
swiftSettings: globalSwiftSettings
139+
),
140+
141+
.testTarget(
142+
name: "CompletionScoringPerfTests",
143+
dependencies: ["CompletionScoring", "CompletionScoringTestSupport", "SwiftExtensions"],
144+
swiftSettings: globalSwiftSettings
145+
),
146+
147+
// MARK: CompletionScoringTestSupport
148+
149+
.target(
150+
name: "CompletionScoringTestSupport",
151+
dependencies: ["CompletionScoring", "SwiftExtensions"],
152+
swiftSettings: globalSwiftSettings
153+
),
154+
114155
// MARK: CSKTestSupport
115156

116157
.target(
@@ -275,6 +316,21 @@ var targets: [Target] = [
275316
swiftSettings: globalSwiftSettings + lspLoggingSwiftSettings
276317
),
277318

319+
.target(
320+
name: "SKLoggingForPlugin",
321+
dependencies: [
322+
"SwiftExtensionsForPlugin"
323+
],
324+
exclude: ["CMakeLists.txt"],
325+
swiftSettings: globalSwiftSettings + lspLoggingSwiftSettings + [
326+
// We can't depend on swift-crypto in the plugin because we can't module-alias it due to https://github.com/swiftlang/swift-package-manager/issues/8119
327+
.define("NO_CRYPTO_DEPENDENCY"),
328+
.unsafeFlags([
329+
"-module-alias", "SwiftExtensions=SwiftExtensionsForPlugin",
330+
]),
331+
]
332+
),
333+
278334
.testTarget(
279335
name: "SKLoggingTests",
280336
dependencies: [
@@ -310,6 +366,21 @@ var targets: [Target] = [
310366
swiftSettings: globalSwiftSettings
311367
),
312368

369+
.target(
370+
name: "SKUtilitiesForPlugin",
371+
dependencies: [
372+
"SKLoggingForPlugin",
373+
"SwiftExtensionsForPlugin",
374+
],
375+
exclude: ["CMakeLists.txt"],
376+
swiftSettings: globalSwiftSettings + [
377+
.unsafeFlags([
378+
"-module-alias", "SKLogging=SKLoggingForPlugin",
379+
"-module-alias", "SwiftExtensions=SwiftExtensionsForPlugin",
380+
])
381+
]
382+
),
383+
313384
.testTarget(
314385
name: "SKUtilitiesTests",
315386
dependencies: [
@@ -356,6 +427,22 @@ var targets: [Target] = [
356427
swiftSettings: globalSwiftSettings
357428
),
358429

430+
.target(
431+
name: "SourceKitDForPlugin",
432+
dependencies: [
433+
"Csourcekitd",
434+
"SKLoggingForPlugin",
435+
"SwiftExtensionsForPlugin",
436+
],
437+
exclude: ["CMakeLists.txt", "sourcekitd_uids.swift.gyb"],
438+
swiftSettings: globalSwiftSettings + [
439+
.unsafeFlags([
440+
"-module-alias", "SKLogging=SKLoggingForPlugin",
441+
"-module-alias", "SwiftExtensions=SwiftExtensionsForPlugin",
442+
])
443+
]
444+
),
445+
359446
.testTarget(
360447
name: "SourceKitDTests",
361448
dependencies: [
@@ -433,6 +520,13 @@ var targets: [Target] = [
433520
swiftSettings: globalSwiftSettings
434521
),
435522

523+
.target(
524+
name: "SwiftExtensionsForPlugin",
525+
dependencies: ["CAtomics"],
526+
exclude: ["CMakeLists.txt"],
527+
swiftSettings: globalSwiftSettings
528+
),
529+
436530
.testTarget(
437531
name: "SwiftExtensionsTests",
438532
dependencies: [
@@ -443,6 +537,84 @@ var targets: [Target] = [
443537
swiftSettings: globalSwiftSettings
444538
),
445539

540+
// MARK: SwiftSourceKitClientPlugin
541+
542+
.target(
543+
name: "SwiftSourceKitClientPlugin",
544+
dependencies: [
545+
"Csourcekitd",
546+
"SourceKitDForPlugin",
547+
"SwiftExtensionsForPlugin",
548+
"SwiftSourceKitPluginCommon",
549+
],
550+
swiftSettings: globalSwiftSettings + [
551+
.unsafeFlags([
552+
"-module-alias", "SourceKitD=SourceKitDForPlugin",
553+
"-module-alias", "SwiftExtensions=SwiftExtensionsForPlugin",
554+
])
555+
],
556+
linkerSettings: sourcekitLSPLinkSettings
557+
),
558+
559+
// MARK: SwiftSourceKitPluginCommon
560+
561+
.target(
562+
name: "SwiftSourceKitPluginCommon",
563+
dependencies: [
564+
"Csourcekitd",
565+
"SourceKitDForPlugin",
566+
"SwiftExtensionsForPlugin",
567+
"SKLoggingForPlugin",
568+
],
569+
swiftSettings: globalSwiftSettings + [
570+
.unsafeFlags([
571+
"-module-alias", "SourceKitD=SourceKitDForPlugin",
572+
"-module-alias", "SwiftExtensions=SwiftExtensionsForPlugin",
573+
"-module-alias", "SKLogging=SKLoggingForPlugin",
574+
])
575+
]
576+
),
577+
578+
// MARK: SwiftSourceKitPlugin
579+
580+
.target(
581+
name: "SwiftSourceKitPlugin",
582+
dependencies: [
583+
"Csourcekitd",
584+
"CompletionScoringForPlugin",
585+
"SKUtilitiesForPlugin",
586+
"SKLoggingForPlugin",
587+
"SourceKitDForPlugin",
588+
"SwiftSourceKitPluginCommon",
589+
"SwiftExtensionsForPlugin",
590+
],
591+
swiftSettings: globalSwiftSettings + [
592+
.unsafeFlags([
593+
"-module-alias", "CompletionScoring=CompletionScoringForPlugin",
594+
"-module-alias", "SKUtilities=SKUtilitiesForPlugin",
595+
"-module-alias", "SourceKitD=SourceKitDForPlugin",
596+
"-module-alias", "SKLogging=SKLoggingForPlugin",
597+
"-module-alias", "SwiftExtensions=SwiftExtensionsForPlugin",
598+
])
599+
],
600+
linkerSettings: sourcekitLSPLinkSettings
601+
),
602+
603+
.testTarget(
604+
name: "SwiftSourceKitPluginTests",
605+
dependencies: [
606+
"BuildSystemIntegration",
607+
"CompletionScoring",
608+
"Csourcekitd",
609+
"LanguageServerProtocol",
610+
"SKTestSupport",
611+
"SourceKitD",
612+
"SwiftExtensions",
613+
"ToolchainRegistry",
614+
],
615+
swiftSettings: globalSwiftSettings
616+
),
617+
446618
// MARK: ToolchainRegistry
447619

448620
.target(
@@ -493,11 +665,11 @@ var targets: [Target] = [
493665
if buildOnlyTests {
494666
products = []
495667
targets = targets.compactMap { target in
496-
guard target.isTest || target.name == "SKTestSupport" else {
668+
guard target.isTest || target.name.contains("TestSupport") else {
497669
return nil
498670
}
499671
target.dependencies = target.dependencies.filter { dependency in
500-
if case .byNameItem(name: "SKTestSupport", _) = dependency {
672+
if case .byNameItem(name: let name, _) = dependency, name.contains("TestSupport") {
501673
return true
502674
}
503675
return false
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
add_library(CCompletionScoring INTERFACE)
2+
target_include_directories(CCompletionScoring INTERFACE "include")
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2025 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+
#ifndef SOURCEKITLSP_CCOMPLETIONSCORING_H
14+
#define SOURCEKITLSP_CCOMPLETIONSCORING_H
15+
16+
#define _GNU_SOURCE
17+
#include <string.h>
18+
19+
static inline void *sourcekitlsp_memmem(const void *haystack, size_t haystack_len, const void *needle, size_t needle_len) {
20+
#if defined(_WIN32) && !defined(__CYGWIN__)
21+
// memmem is not available on Windows
22+
if (!haystack || haystack_len == 0) {
23+
return NULL;
24+
}
25+
if (!needle || needle_len == 0) {
26+
return NULL;
27+
}
28+
if (needle_len > haystack_len) {
29+
return NULL;
30+
}
31+
32+
for (size_t offset = 0; offset <= haystack_len - needle_len; ++offset) {
33+
if (memcmp(haystack + offset, needle, needle_len) == 0) {
34+
return (void *)haystack + offset;
35+
}
36+
}
37+
return NULL;
38+
#else
39+
return memmem(haystack, haystack_len, needle, needle_len);
40+
#endif
41+
}
42+
43+
#endif // SOURCEKITLSP_CCOMPLETIONSCORING_H
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
module CCompletionScoring {
2+
header "CCompletionScoring.h"
3+
export *
4+
}

Sources/CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ add_compile_options("$<$<COMPILE_LANGUAGE:Swift>:SHELL:-swift-version 6>")
44
add_subdirectory(BuildServerProtocol)
55
add_subdirectory(BuildSystemIntegration)
66
add_subdirectory(CAtomics)
7+
add_subdirectory(CCompletionScoring)
8+
add_subdirectory(CompletionScoring)
79
add_subdirectory(Csourcekitd)
810
add_subdirectory(Diagnose)
911
add_subdirectory(InProcessClient)
@@ -18,5 +20,8 @@ add_subdirectory(SourceKitLSP)
1820
add_subdirectory(SourceKitD)
1921
add_subdirectory(sourcekit-lsp)
2022
add_subdirectory(SwiftExtensions)
23+
add_subdirectory(SwiftSourceKitClientPlugin)
24+
add_subdirectory(SwiftSourceKitPlugin)
25+
add_subdirectory(SwiftSourceKitPluginCommon)
2126
add_subdirectory(ToolchainRegistry)
2227
add_subdirectory(TSCExtensions)
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
set(sources
2+
Semantics/SemanticClassification.swift
3+
Semantics/CompletionScore.swift
4+
Semantics/Components
5+
Semantics/Components/TypeCompatibility.swift
6+
Semantics/Components/StructuralProximity.swift
7+
Semantics/Components/Flair.swift
8+
Semantics/Components/CompletionKind.swift
9+
Semantics/Components/Popularity.swift
10+
Semantics/Components/ScopeProximity.swift
11+
Semantics/Components/Availability.swift
12+
Semantics/Components/SynchronicityCompatibility.swift
13+
Semantics/Components/PopularityIndex.swift
14+
Semantics/Components/ModuleProximity.swift
15+
Semantics/Components/PopularityTable.swift
16+
Utilities/UnsafeStackAllocator.swift
17+
Utilities/Serialization
18+
Utilities/Serialization/BinaryCodable.swift
19+
Utilities/Serialization/BinaryEncoder.swift
20+
Utilities/Serialization/BinaryDecoder.swift
21+
Utilities/Serialization/Conformances
22+
Utilities/Serialization/Conformances/Dictionary+BinaryCodable.swift
23+
Utilities/Serialization/Conformances/OptionSet+BinaryCodable.swift
24+
Utilities/Serialization/Conformances/Optional+BinaryCodable.swift
25+
Utilities/Serialization/Conformances/Scalars+BinaryCodable.swift
26+
Utilities/Serialization/Conformances/String+BinaryCodable.swift
27+
Utilities/Serialization/Conformances/Array+BinaryCodable.swift
28+
Utilities/SwiftExtensions.swift
29+
Utilities/SelectTopK.swift
30+
Utilities/UnsafeArray.swift
31+
Text/CandidateBatch.swift
32+
Text/MatchCollator.Match.swift
33+
Text/UTF8Byte.swift
34+
Text/MatchCollator.swift
35+
Text/InfluencingIdentifiers.swift
36+
Text/MatchCollator.Selection.swift
37+
Text/ScoredMatchSelector.swift
38+
Text/RejectionFilter.swift
39+
Text/Pattern.swift)
40+
41+
add_library(CompletionScoring STATIC ${sources})
42+
set_target_properties(CompletionScoring PROPERTIES
43+
INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_Swift_MODULE_DIRECTORY})
44+
target_link_libraries(CompletionScoring PUBLIC
45+
CCompletionScoring)
46+
47+
add_library(CompletionScoringForPlugin STATIC ${sources})
48+
set_target_properties(CompletionScoringForPlugin PROPERTIES
49+
INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_Swift_MODULE_DIRECTORY})
50+
target_link_libraries(CompletionScoringForPlugin PUBLIC
51+
CCompletionScoring)

0 commit comments

Comments
 (0)