The `WorkspaceConfiguration.default` was being used to populate
the `Workspace`; there was an extra step here needed to assure that
we are propagating the trait configuration to the workspace.
The added test assures that non-default traits that are enabled are
indeed processed as enabled.
For ID counters and standalone flags (most sites), drop to .relaxed
since nothing reads other memory based on the atomic's value.
MultiEntrySemaphore.signaled is the exception: it is used as a
signal/wait primitive where waiters proceed to use state set up
before signal(). Use .releasing on store and .acquiring on load so
that pre-signal writes are visible to waiters that observe `true`.
.relaxed there would be incorrect on weakly-ordered architectures.
Replace AtomicBool/UInt8/UInt32/Int32 from
ToolsProtocolsSwiftExtensions with Synchronization.Atomic<T> where
the storage is a static, module-level let, or class stored property.
For local lets captured by @Sendable closures (where Atomic's
~Copyable nature prevents capture), use ThreadSafeBox<T> instead.
SwiftPM PR #9985 introduce files in the scratch path whose contents
indicate which build system was used to build artifact for a given build
configuration. if this file exist, use it's contents to infer the build
system. Otherwise, fallback to the existing behaviour.
Fixes: #2576
Binary targets backed by remote `.artifactbundleindex` URLs cause
SwiftPM to re-extract the artifact bundle into the scratch directory
on every package load. The resulting file-change events (delete +
create) for the extracted files triggered another reload, causing an
infinite loop.
Add `isInScratchDirectory` to `fileEventShouldTriggerPackageReload`
to filter out events before the build-settings check. It covers
both the configured scratch directory and the default `.build/`
directory (which receives regular `swift build` output even when
a custom scratch path is configured).
Also add tests using local zip-based binary targets to cover both
the default and custom-scratch-path scenarios. Local zips are used
in the tests to avoid a network dependency; they exercise the same
`isInScratchDirectory` code path even though the infinite loop in
practice requires a remote `.artifactbundleindex` target (where
SwiftPM's checksum mismatch causes re-extraction on every load).
https://github.com/swiftlang/sourcekit-lsp/issues/2615
Replace usages of `Optional.map` and `Optional.flatMap` by if expressions or other expressions.
I personally find `Optional.map` to be hard to read because `map` implies mapping a collection to me. Usually the alternative constructs seem clearer to me.
If a workspace was opened as `/path/to/workspace` instead of `/path/to/workspace/` (notice the trailing slash), the check for `url.deletingLastPathComponent() == self.projectRoot` failed because deleting the last path component always produces a URL with a trailing slash and URL considers two path different if they mismatch in their trailing slash usage.
Use `DocumentURI` for equality checking, which is a little more lenient with declaring equality, including with regard to trailing slashes, and whose equality definition aligns better with what we want in SourceKit-LSP.
I searched for other usages of `==` between URLs and there doesn’t seem to be any similar issues.
When I added the log structure to `build/logMessage` in #2022 I must have assumed that the entire BSP notifciation was an extension defined by SourceKit-LSP and didn’t realized that this was actually a change that made the notification non-compliant with BSP. Change it up a little bit to make it compliant again.
Two improvements to the logic that determines if we need to reload the package on a file change:
1. Only reload a package if the modified package manifest or Package.resolved is in the root of the package folder. This is relevant if we have a multi-root workspace, in which currently a single change to a package manifest or Package.resolved causes all packages to get reloaded.
2. While I was at it, I noticed that we didn’t properly handle version-specific package manifests. Also trigger a package reload if a version-specific package manifest is modified, created or deleted.
We already had logic to retry loading a package manifest if writing the output-file-map failed. This only covered errors thrown from Foundation but I was seeing similar errors from TSC. Cover those as well.
If a call in `reloadPackageAssumingOnPackageLoadingQueue` throws, we weren’t getting to the end of it and would thus never end the signpost started within. Move the `endInterval` call up ensure it is always ended.
Found this while investigating https://ci-external.swift.org/job/swift-PR-windows/44247/console, which failed SourceKit-LSP testing because PackageA could not be loaded due to
```
Initial package loading: invalid access to C:\Users\swift-ci\jenkins\workspace\swift-PR-windows\build\tmp\lsp-test\924F7085\PackageA\.build\index-build\x86_64-unknown-windows-msvc\debug\MyLibrary.build\output-file-map.json
```
The term *build system* predated our wide-spread adoption of BSP for communicating between SourceKit-LSP to the build system and was never really the correct term anyway – ie. a `JSONCompilationDatabaseBuildSystem` never really sounded right. We now have a correct term for the communication layer between SourceKit-LSP: A build server. Rename most occurrences of *build system* to *build server* to reflect this. There are unfortunately a couple lingering instances of *build system* that we can’t change, most notably: `fallbackBuildSystem` in the config file, the `workspace/waitForBuildSystemUpdates` BSP extension request and the `synchronize-for-build-system-updates` experimental feature.