-
Notifications
You must be signed in to change notification settings - Fork 314
Keep track of build settings in BuildSystemManager
instead of SourceKitServer
#841
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
Keep track of build settings in BuildSystemManager
instead of SourceKitServer
#841
Conversation
ea6158f
to
9a2c57f
Compare
@swift-ci Please test |
@swift-ci Please test macOS |
…mManagerTests` to get build settings
…not about new build settings This defines away an entire class of data races if delegate callbacks are delivered out-of-order. If we aren’t providing the new build settings in the delegate callback, then it doesn’t matter if two `fileBuildSettingsChanged` calls change order since they don’t carry any state.
…d `BuildSystemManager` The core idea here is that the toolchain language servers always call into `BuildSystemManager` and `BuildSystemManager` will always reply with build settings. If it hasn’t computed them yet, it will reply with fallback settings. With that assumption, we can remove the `documentToPendingQueue` from `SourceKitServer` since there are no longer any documents that are pending – everything has a build settings immediately. Similarly, `BuildSystemManager.mainFileStatuses` also isn’t needed anymore. And lastly, since we know that `BuildSystemManager.buildSettings` will always return a value `registerForChangeNotifications` is changed not call `fileBuildSettingsChanged` immediately. Instead, it will only cause `fileBuildSettingsChanged` to be called when the file’s build settings change after the `registerForChangeNotifications` call.
9a2c57f
to
c642b37
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice!
for document: DocumentURI, | ||
language: Language | ||
) async -> (buildSettings: FileBuildSettings, isFallback: Bool)? { | ||
if let mainFile = mainFilesProvider?.mainFilesContainingFile(document).first { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As I understand it, mainFilesContainingFile
returns a Set
, do we need to worry about the lack of a stable ordering when accessing first
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah I see this is copying chooseMainFile
, do we need to worry there too?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It turned out that this was a good area to refactor and it got a little bit larger and more involved. I will open a follow-up PR for it.
// If the document is ready, we can handle it right now. | ||
guard !self.documentsReady.contains(doc) else { | ||
await requestHandler(request, workspace, languageService) | ||
return | ||
} | ||
|
||
// Not ready to handle it, we'll queue it and handle it later. | ||
self.documentToPendingQueue[doc, default: DocumentNotificationRequestQueue()].add(operation: { | ||
await requestHandler(request, workspace, languageService) | ||
}, cancellationHandler: { | ||
request.reply(fallback) | ||
}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🎉
After two minor preliminary commits, there are two core commits here that go hand-in-hand and significantly simplify the build settings handling.
Change the build system to only notify delegate about changed files, not about new build settings
This defines away an entire class of data races if delegate callbacks are delivered out-of-order. If we aren’t providing the new build settings in the delegate callback, then it doesn’t matter if two
fileBuildSettingsChanged
calls change order since they don’t carry any state. Instead of storing the build settings returned by the delegate call, the language server needs to ask theBuildSystemManager
for the current build settings of the file.Remove tracking of file build settings status in
SourceKitServer
andBuildSystemManager
The core idea here is that the toolchain language servers always call into
BuildSystemManager
andBuildSystemManager
will always reply with build settings. If it hasn’t computed them yet, it will reply with fallback settings.With that assumption, we can remove the
documentToPendingQueue
fromSourceKitServer
since there are no longer any documents that are pending – everything has a build settings immediately.Similarly,
BuildSystemManager.mainFileStatuses
also isn’t needed anymore.And lastly, since we know that
BuildSystemManager.buildSettings
will always return a valueregisterForChangeNotifications
is changed not callfileBuildSettingsChanged
immediately. Instead, it will only causefileBuildSettingsChanged
to be called when the file’s build settings change after theregisterForChangeNotifications
call.